This repository has been archived on 2026-08-27. You can view files and clone it, but cannot push or open issues or pull requests.
gopher64-netplay/src/device/cop2.rs
Logan McNaughton 2e4a23c315 Initial Commit
2023-10-04 14:33:17 -06:00

138 lines
5.4 KiB
Rust

use crate::device;
pub struct Cop2 {
pub instrs: [fn(&mut device::Device, u32); 32],
pub reg_latch: u64,
}
pub fn mfc2(device: &mut device::Device, opcode: u32) {
device.cpu.gpr[device::cpu_instructions::rt(opcode) as usize] =
device::cpu_instructions::se32((device.cpu.cop2.reg_latch) as u32 as i32)
}
pub fn dmfc2(device: &mut device::Device, opcode: u32) {
device.cpu.gpr[device::cpu_instructions::rt(opcode) as usize] = device.cpu.cop2.reg_latch
}
pub fn cfc2(device: &mut device::Device, opcode: u32) {
device.cpu.gpr[device::cpu_instructions::rt(opcode) as usize] =
device::cpu_instructions::se32((device.cpu.cop2.reg_latch) as u32 as i32)
}
pub fn mtc2(device: &mut device::Device, opcode: u32) {
device.cpu.cop2.reg_latch = device.cpu.gpr[device::cpu_instructions::rt(opcode) as usize]
}
pub fn dmtc2(device: &mut device::Device, opcode: u32) {
device.cpu.cop2.reg_latch = device.cpu.gpr[device::cpu_instructions::rt(opcode) as usize]
}
pub fn ctc2(device: &mut device::Device, opcode: u32) {
device.cpu.cop2.reg_latch = device.cpu.gpr[device::cpu_instructions::rt(opcode) as usize]
}
pub fn reserved(device: &mut device::Device, _opcode: u32) {
device::exceptions::reserved_exception(device, device::cop0::COP0_CAUSE_CE2);
}
pub fn unusable(device: &mut device::Device, _opcode: u32) {
device::exceptions::cop_unusable_exception(device, device::cop0::COP0_CAUSE_CE2)
}
pub fn init(device: &mut device::Device) {
set_usable(device, false);
}
pub fn set_usable(device: &mut device::Device, usable: bool) {
if !usable {
device.cpu.cop2.instrs = [
device::cop2::unusable, // 0
device::cop2::unusable, // 1
device::cop2::unusable, // 2
device::cop2::unusable, // 3
device::cop2::unusable, // 4
device::cop2::unusable, // 5
device::cop2::unusable, // 6
device::cop2::unusable, // 7
device::cop2::unusable, // 8
device::cop2::unusable, // 9
device::cop2::unusable, // 10
device::cop2::unusable, // 11
device::cop2::unusable, // 12
device::cop2::unusable, // 13
device::cop2::unusable, // 14
device::cop2::unusable, // 15
device::cop2::unusable, // 16
device::cop2::unusable, // 17
device::cop2::unusable, // 18
device::cop2::unusable, // 19
device::cop2::unusable, // 20
device::cop2::unusable, // 21
device::cop2::unusable, // 22
device::cop2::unusable, // 23
device::cop2::unusable, // 24
device::cop2::unusable, // 25
device::cop2::unusable, // 26
device::cop2::unusable, // 27
device::cop2::unusable, // 28
device::cop2::unusable, // 29
device::cop2::unusable, // 30
device::cop2::unusable, // 31
]
} else {
device.cpu.cop2.instrs = [
device::cop2::mfc2, // 0
device::cop2::dmfc2, // 1
device::cop2::cfc2, // 2
device::cop2::reserved, // 3
device::cop2::mtc2, // 4
device::cop2::dmtc2, // 5
device::cop2::ctc2, // 6
device::cop2::reserved, // 7
device::cop2::reserved, // 8
device::cop2::reserved, // 9
device::cop2::reserved, // 10
device::cop2::reserved, // 11
device::cop2::reserved, // 12
device::cop2::reserved, // 13
device::cop2::reserved, // 14
device::cop2::reserved, // 15
device::cop2::reserved, // 16
device::cop2::reserved, // 17
device::cop2::reserved, // 18
device::cop2::reserved, // 19
device::cop2::reserved, // 20
device::cop2::reserved, // 21
device::cop2::reserved, // 22
device::cop2::reserved, // 23
device::cop2::reserved, // 24
device::cop2::reserved, // 25
device::cop2::reserved, // 26
device::cop2::reserved, // 27
device::cop2::reserved, // 28
device::cop2::reserved, // 29
device::cop2::reserved, // 30
device::cop2::reserved, // 31
]
}
// we have to recalculate the instruction pointers in the icache
for i in 0..512 {
device.memory.icache[i].instruction[0] =
device::cpu::decode_opcode(device, device.memory.icache[i].words[0]);
device.memory.icache[i].instruction[1] =
device::cpu::decode_opcode(device, device.memory.icache[i].words[1]);
device.memory.icache[i].instruction[2] =
device::cpu::decode_opcode(device, device.memory.icache[i].words[2]);
device.memory.icache[i].instruction[3] =
device::cpu::decode_opcode(device, device.memory.icache[i].words[3]);
device.memory.icache[i].instruction[4] =
device::cpu::decode_opcode(device, device.memory.icache[i].words[4]);
device.memory.icache[i].instruction[5] =
device::cpu::decode_opcode(device, device.memory.icache[i].words[5]);
device.memory.icache[i].instruction[6] =
device::cpu::decode_opcode(device, device.memory.icache[i].words[6]);
device.memory.icache[i].instruction[7] =
device::cpu::decode_opcode(device, device.memory.icache[i].words[7])
}
}