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/events.rs
Logan McNaughton 4a63f469bf
update VI on V_START (#1050)
* update VI on V_START

* more

* more

* more

* more
2026-06-10 08:55:51 +00:00

107 lines
3.4 KiB
Rust

use crate::device;
use crate::ui;
pub const EVENT_TYPE_NONE: usize = 0;
pub const EVENT_TYPE_AI: usize = 1;
pub const EVENT_TYPE_SI: usize = 2;
pub const EVENT_TYPE_VI: usize = 3;
pub const EVENT_TYPE_PI: usize = 4;
pub const EVENT_TYPE_DP: usize = 5;
pub const EVENT_TYPE_SP: usize = 6;
pub const EVENT_TYPE_INT: usize = 7;
pub const EVENT_TYPE_SPDMA: usize = 8;
pub const EVENT_TYPE_COMPARE: usize = 9;
pub const EVENT_TYPE_VRU: usize = 10;
pub const EVENT_TYPE_PAK: usize = 11;
pub const EVENT_TYPE_SAVE: usize = 12;
pub const EVENT_TYPE_NMI: usize = 13;
pub const EVENT_TYPE_UPDATE_SCREEN: usize = 14;
pub const EVENT_TYPE_COUNT: usize = 15;
#[derive(PartialEq, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub struct Event {
pub enabled: bool,
pub count: u64,
}
pub fn create_event(device: &mut device::Device, name: usize, when: u64) {
device.cpu.events[name] = Event {
enabled: true,
count: device.cpu.cop0.regs[device::cop0::COP0_COUNT_REG] + when,
};
set_next_event(device);
}
pub fn create_event_at(device: &mut device::Device, name: usize, when: u64) {
device.cpu.events[name] = Event {
enabled: true,
count: when,
};
set_next_event(device);
}
pub fn get_event(device: &device::Device, name: usize) -> Option<&Event> {
if device.cpu.events[name].enabled {
return Some(&device.cpu.events[name]);
}
None
}
pub fn remove_event(device: &mut device::Device, name: usize) {
device.cpu.events[name].enabled = false;
}
fn get_event_handler(name: usize) -> fn(&mut device::Device) {
match name {
EVENT_TYPE_AI => device::ai::dma_event,
EVENT_TYPE_SI => device::si::dma_event,
EVENT_TYPE_VI => device::vi::vertical_interrupt_event,
EVENT_TYPE_PI => device::pi::dma_event,
EVENT_TYPE_DP => device::rdp::rdp_interrupt_event,
EVENT_TYPE_SP => device::rsp_interface::rsp_event,
EVENT_TYPE_INT => device::exceptions::interrupt_exception,
EVENT_TYPE_SPDMA => device::rsp_interface::fifo_pop,
EVENT_TYPE_COMPARE => device::cop0::compare_event,
EVENT_TYPE_VRU => device::controller::vru::vru_talking_event,
EVENT_TYPE_PAK => device::controller::pak_switch_event,
EVENT_TYPE_SAVE => ui::storage::save_event,
EVENT_TYPE_NMI => device::exceptions::reset_event,
EVENT_TYPE_UPDATE_SCREEN => device::vi::update_screen,
_ => dummy_event,
}
}
pub fn trigger_event(device: &mut device::Device) {
let next_event_name = device.cpu.next_event;
device.cpu.events[next_event_name].enabled = false;
let handler = get_event_handler(next_event_name);
device.cpu.cop0.is_event = true;
handler(device);
device.cpu.cop0.is_event = false;
set_next_event(device);
}
fn set_next_event(device: &mut device::Device) {
device.cpu.next_event_count = u64::MAX;
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 = pos;
}
}
}
pub fn translate_events(device: &mut device::Device, old_count: u64, new_count: u64) {
for i in device.cpu.events.iter_mut() {
if i.enabled {
i.count = i.count - old_count + new_count;
}
}
set_next_event(device);
}
pub fn dummy_event(_device: &mut device::Device) {
panic!("dummy event")
}