const PRID: u32 = 0x2;
#[derive(Default)]
pub struct SystemControlCoprocessor {
bpc: u32,
bda: u32,
jmp_dest: u32,
dcic: u32,
bad_vaddr: u32,
bdam: u32,
bpcm: u32,
sr: u32,
cause: u32,
epc: u32,
}
impl SystemControlCoprocessor {
pub fn is_cache_isolated(&self) -> bool {
self.sr & 0x10000 != 0
}
pub fn read_cause(&self) -> u32 {
self.cause
}
pub fn write_cause(&mut self, data: u32) {
self.cause = data;
}
pub fn read_sr(&self) -> u32 {
self.sr
}
pub fn write_sr(&mut self, data: u32) {
self.sr = data;
}
pub fn write_epc(&mut self, data: u32) {
self.epc = data;
}
pub fn write_bad_vaddr(&mut self, addr: u32) {
self.bad_vaddr = addr;
}
}
impl SystemControlCoprocessor {
pub fn read_ctrl(&self, num: u8) -> u32 {
assert!(num <= 0x1F);
todo!("cop0 ctrl read {}", num)
}
pub fn write_ctrl(&mut self, num: u8, data: u32) {
assert!(num <= 0x1F);
todo!("cop0 ctrl write {}, data={:08X}", num, data)
}
pub fn read_data(&self, num: u8) -> u32 {
assert!(num <= 0x1F);
let out = match num {
6 => self.jmp_dest,
7 => self.dcic,
8 => self.bad_vaddr,
12 => self.sr,
13 => self.cause,
14 => self.epc,
15 => PRID,
16..=31 => 0xFF,
0..=15 => todo!("cop0 data read {}", num),
_ => unreachable!(),
};
log::info!("cop0 data read {}, data={:08X}", num, out);
out
}
pub fn write_data(&mut self, num: u8, data: u32) {
assert!(num <= 0x1F);
log::info!("cop0 data write {}, data={:08X}", num, data);
match num {
3 => self.bpc = data,
5 => self.bda = data,
6 => {}
7 => self.dcic = data,
9 => self.bdam = data,
11 => self.bpcm = data,
12 => self.sr = data,
13 => {
self.cause &= !0x300;
self.cause |= data & 0x300;
}
16..=31 => {} 0..=15 => todo!("cop0 data write {}, vaule {:08X}", num, data),
_ => unreachable!(),
}
}
}