mirror of
https://github.com/gopher64/gopher64.git
synced 2026-07-11 01:25:20 +02:00
cache rsp opcode
This commit is contained in:
+4
-1
@@ -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,
|
||||
|
||||
+10
-7
@@ -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 => {
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user