diff --git a/src/device.rs b/src/device.rs index 9ba82247..6b3fcb18 100644 --- a/src/device.rs +++ b/src/device.rs @@ -184,7 +184,10 @@ impl Device { rdram: rdram::Rdram { mem: vec![] }, rsp: rsp_interface::Rsp { cpu: rsp_cpu::Cpu { - instructions: [rsp_su_instructions::reserved; 0x1000 / 4], + instructions: [rsp_cpu::Instructions { + func: rsp_su_instructions::reserved, + opcode: 0, + }; 0x1000 / 4], last_instruction_type: rsp_cpu::InstructionType::Su, instruction_type: rsp_cpu::InstructionType::Su, pipeline_full: false, diff --git a/src/device/rsp_cpu.rs b/src/device/rsp_cpu.rs index d5bf54e8..f2788a53 100644 --- a/src/device/rsp_cpu.rs +++ b/src/device/rsp_cpu.rs @@ -6,6 +6,12 @@ pub struct BranchState { pub pc: u32, } +#[derive(Copy, Clone)] +pub struct Instructions { + pub func: fn(&mut device::Device, u32), + pub opcode: u32, +} + #[derive(PartialEq, Copy, Clone)] pub enum InstructionType { Su, @@ -13,7 +19,7 @@ pub enum InstructionType { } pub struct Cpu { - pub instructions: [fn(&mut device::Device, u32); 0x1000 / 4], + pub instructions: [Instructions; 0x1000 / 4], pub last_instruction_type: InstructionType, pub instruction_type: InstructionType, pub pipeline_full: bool, @@ -62,13 +68,10 @@ pub fn run(device: &mut device::Device) -> u64 { while !device.rsp.cpu.sync_point { device.rsp.cpu.instruction_type = InstructionType::Su; device.rsp.cpu.gpr[0] = 0; // gpr 0 is read only - let offset = 0x1000 + device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] as usize; - let opcode = u32::from_be_bytes(device.rsp.mem[offset..offset + 4].try_into().unwrap()); - device.rsp.cpu.instructions - [(device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] / 4) as usize]( - device, opcode, - ); + let instruction = device.rsp.cpu.instructions + [(device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] / 4) as usize]; + (instruction.func)(device, instruction.opcode); match device.rsp.cpu.branch_state.state { device::cpu::State::Step => { diff --git a/src/device/rsp_interface.rs b/src/device/rsp_interface.rs index 3f561287..37ca1ed6 100644 --- a/src/device/rsp_interface.rs +++ b/src/device/rsp_interface.rs @@ -121,8 +121,9 @@ pub fn write_mem(device: &mut device::Device, address: u64, value: u32, _mask: u if masked_address & 0x1000 != 0 { // imem being updated - device.rsp.cpu.instructions[((masked_address & 0xFFF) / 4) as usize] = + device.rsp.cpu.instructions[((masked_address & 0xFFF) / 4) as usize].func = device::rsp_cpu::decode_opcode(device, data); + device.rsp.cpu.instructions[((masked_address & 0xFFF) / 4) as usize].opcode = data; } // SH/SB are broken: They overwrite the whole 32 bit, filling everything that isn't written with zeroes @@ -171,8 +172,9 @@ pub fn do_dma(device: &mut device::Device, dma: RspDma) { ); if offset != 0 { // imem being updated - device.rsp.cpu.instructions[((mem_addr & 0xFFF) / 4) as usize] = + device.rsp.cpu.instructions[((mem_addr & 0xFFF) / 4) as usize].func = device::rsp_cpu::decode_opcode(device, data); + device.rsp.cpu.instructions[((mem_addr & 0xFFF) / 4) as usize].opcode = data; } device.rsp.mem[(offset + (mem_addr & 0xFFF)) as usize ..(offset + (mem_addr & 0xFFF)) as usize + 4]