From 3edbca1485b5aa1fcf7c8f67afc0ba7a7c1f1f38 Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Thu, 5 Oct 2023 19:57:12 -0600 Subject: [PATCH] Events cleanup (#7) * cleanup * more * more * clean --- Cargo.toml | 1 - build_debug.sh | 3 +++ src/device.rs | 8 ++++++-- src/device/cop0.rs | 6 +++--- src/device/cpu.rs | 4 ++-- src/device/events.rs | 48 ++++++++++++++++--------------------------- src/device/rsp_cpu.rs | 11 +++++----- 7 files changed, 37 insertions(+), 44 deletions(-) create mode 100755 build_debug.sh diff --git a/Cargo.toml b/Cargo.toml index 342f5c8..353e2e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,4 +21,3 @@ cc = { version = "1.0", features = ["parallel"] } [profile.release] lto = true codegen-units = 1 -debug = 1 diff --git a/build_debug.sh b/build_debug.sh new file mode 100755 index 0000000..2879946 --- /dev/null +++ b/build_debug.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +RUSTFLAGS='-C target-cpu=x86-64-v3' cargo build diff --git a/src/device.rs b/src/device.rs index ecba004..f5e80a7 100644 --- a/src/device.rs +++ b/src/device.rs @@ -134,9 +134,13 @@ impl Device { instrs: [cop0::reserved; 64], special_instrs: [cop0::reserved; 64], regimm_instrs: [cop0::reserved; 32], - events: vec![], + events: [events::Event { + enabled: false, + count: u64::MAX, + handler: events::dummy_event, + }; events::EventType::EventTypeCount as usize], next_event_count: u64::MAX, - next_event: None, + next_event: 0, }, pif: pif::Pif { rom: [0; 1984], diff --git a/src/device/cop0.rs b/src/device/cop0.rs index 121c236..a1d7654 100644 --- a/src/device/cop0.rs +++ b/src/device/cop0.rs @@ -202,7 +202,7 @@ pub fn set_control_registers(device: &mut device::Device, index: u32, mut data: event_time += !0 as u32 as u64 } let compare_event: &mut device::events::Event = - device::events::get_event(device, device::events::EventType::COMPARE).unwrap(); + device::events::get_event(device, device::events::EventType::Compare).unwrap(); compare_event.count = event_time; // reschedule the next compare interrupt event device::events::set_next_event(device); device.cpu.cop0.regs[COP0_CAUSE_REG as usize] &= !COP0_CAUSE_IP7; @@ -228,7 +228,7 @@ pub fn compare_event(device: &mut device::Device) { device::events::create_event( device, - device::events::EventType::COMPARE, + device::events::EventType::Compare, device.cpu.next_event_count + (!0 as u32 as u64), compare_event, ); @@ -364,7 +364,7 @@ pub fn init(device: &mut device::Device) { device::events::create_event( device, - device::events::EventType::COMPARE, + device::events::EventType::Compare, !0 as u32 as u64, compare_event, ) diff --git a/src/device/cpu.rs b/src/device/cpu.rs index 12fe8ae..e56db38 100644 --- a/src/device/cpu.rs +++ b/src/device/cpu.rs @@ -30,9 +30,9 @@ pub struct Cpu { pub instrs: [fn(&mut device::Device, u32); 64], pub special_instrs: [fn(&mut device::Device, u32); 64], pub regimm_instrs: [fn(&mut device::Device, u32); 32], - pub events: Vec, + pub events: [device::events::Event; device::events::EventType::EventTypeCount as usize], pub next_event_count: u64, - pub next_event: Option, + pub next_event: usize, } pub fn decode_opcode(device: &mut device::Device, opcode: u32) -> fn(&mut device::Device, u32) { diff --git a/src/device/events.rs b/src/device/events.rs index 900e23b..59c8eb3 100644 --- a/src/device/events.rs +++ b/src/device/events.rs @@ -9,12 +9,13 @@ pub enum EventType { DP, SP, SPDma, - COMPARE, + Compare, + EventTypeCount, } #[derive(PartialEq, Copy, Clone)] pub struct Event { - pub name: EventType, + pub enabled: bool, pub count: u64, pub handler: fn(&mut device::Device), } @@ -25,57 +26,40 @@ pub fn create_event( when: u64, handler: fn(&mut device::Device), ) { - let event = Event { - name: name, + device.cpu.events[name as usize] = Event { + enabled: true, count: when, handler: handler, }; - if get_event(device, name) != None { - panic! {"duplicate event {}", name as usize} - } - device.cpu.events.push(event); set_next_event(device); } pub fn get_event(device: &mut device::Device, name: EventType) -> Option<&mut Event> { - for i in device.cpu.events.iter_mut() { - if i.name == name { - return Some(i); - } + if device.cpu.events[name as usize].enabled { + return Some(&mut device.cpu.events[name as usize]); } return None; } pub fn remove_event(device: &mut device::Device, name: EventType) { - let mut remove_index: usize = 0; - let mut found = false; - for (pos, i) in device.cpu.events.iter_mut().enumerate() { - if i.name == name { - found = true; - remove_index = pos; - break; - } - } - if found { - device.cpu.events.remove(remove_index); - } + device.cpu.events[name as usize].enabled = false; } pub fn trigger_event(device: &mut device::Device) { - let next_event_name = device.cpu.next_event.unwrap().name; - remove_event(device, next_event_name); + let next_event_name = device.cpu.next_event; + device.cpu.events[next_event_name].enabled = false; - let handler = device.cpu.next_event.unwrap().handler; + let handler = device.cpu.events[next_event_name].handler; handler(device); set_next_event(device); } pub fn set_next_event(device: &mut device::Device) { device.cpu.next_event_count = u64::MAX; - for i in device.cpu.events.iter() { - if i.count < device.cpu.next_event_count { + for (pos, i) in device.cpu.events.iter().enumerate() { + if i.enabled && i.count < device.cpu.next_event_count { device.cpu.next_event_count = i.count; - device.cpu.next_event = Some(*i); + device.cpu.next_event = pos; } } } @@ -86,3 +70,7 @@ pub fn translate_events(device: &mut device::Device, old_count: u64, new_count: } set_next_event(device); } + +pub fn dummy_event(_device: &mut device::Device) { + panic!("dummy event") +} diff --git a/src/device/rsp_cpu.rs b/src/device/rsp_cpu.rs index da0c5b7..15d40ca 100644 --- a/src/device/rsp_cpu.rs +++ b/src/device/rsp_cpu.rs @@ -58,7 +58,7 @@ pub fn in_delay_slot_taken(device: &mut device::Device) -> bool { pub fn run(device: &mut device::Device) -> u64 { device.rsp.cpu.broken = false; let mut cycle_counter = 0; - while !device.rsp.cpu.halted && !device.rsp.cpu.sync_point { + 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; @@ -66,7 +66,10 @@ pub fn run(device: &mut device::Device) -> u64 { execute_opcode(device, opcode)(device, opcode); match device.rsp.cpu.branch_state.state { device::cpu::State::Step => { - device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] += 4 + device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] += 4; + if device.rsp.cpu.broken { + break; + } } device::cpu::State::Take => { device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] += 4; @@ -107,10 +110,6 @@ pub fn run(device: &mut device::Device) -> u64 { device.rsp.cpu.pipeline_full = true; } } - - if device.rsp.cpu.broken && device.rsp.cpu.branch_state.state == device::cpu::State::Step { - break; - } } return (cycle_counter as f64 * 1.5) as u64; // converting RCP clock to CPU clock }