Events cleanup (#7)

* cleanup

* more

* more

* clean
This commit is contained in:
Logan McNaughton
2023-10-05 19:57:12 -06:00
committed by GitHub
parent fde0af6f9b
commit 3edbca1485
7 changed files with 37 additions and 44 deletions
-1
View File
@@ -21,4 +21,3 @@ cc = { version = "1.0", features = ["parallel"] }
[profile.release]
lto = true
codegen-units = 1
debug = 1
Executable
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
RUSTFLAGS='-C target-cpu=x86-64-v3' cargo build
+6 -2
View File
@@ -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],
+3 -3
View File
@@ -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,
)
+2 -2
View File
@@ -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<device::events::Event>,
pub events: [device::events::Event; device::events::EventType::EventTypeCount as usize],
pub next_event_count: u64,
pub next_event: Option<device::events::Event>,
pub next_event: usize,
}
pub fn decode_opcode(device: &mut device::Device, opcode: u32) -> fn(&mut device::Device, u32) {
+18 -30
View File
@@ -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")
}
+5 -6
View File
@@ -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
}