diff --git a/build.rs b/build.rs index 807dcd36..1725dea1 100644 --- a/build.rs +++ b/build.rs @@ -99,6 +99,7 @@ fn main() { .allowlist_function("rdp_set_vi_register") .allowlist_function("rdp_update_screen") .allowlist_function("rdp_process_commands") + .allowlist_function("rdp_full_sync") .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) .generate() .expect("Unable to generate bindings"); diff --git a/parallel-rdp/interface.cpp b/parallel-rdp/interface.cpp index 8be5c43d..aff96c0c 100644 --- a/parallel-rdp/interface.cpp +++ b/parallel-rdp/interface.cpp @@ -62,6 +62,7 @@ static int cmd_cur; static int cmd_ptr; static bool emu_running; static GFX_INFO gfx_info; +static uint64_t sync_signal; static const unsigned cmd_len_lut[64] = { 1, @@ -330,45 +331,6 @@ bool rdp_update_screen() return emu_running; } -static uint32_t viCalculateHorizonalWidth(uint32_t hstart, uint32_t xscale, uint32_t width) -{ - if (xscale == 0) - return 320; - - uint32_t start = ((hstart & 0x03FF0000) >> 16) & 0x3FF; - uint32_t end = (hstart & 0x3FF); - uint32_t delta; - if (end > start) - delta = end - start; - else - delta = start - end; - uint32_t scale = (xscale & 0xFFF); - - if (delta == 0) - { - delta = width; - } - - return (delta * scale) / 0x400; -} - -static uint32_t viCalculateVerticalHeight(uint32_t vstart, uint32_t yscale) -{ - if (yscale == 0) - return 240; - - uint32_t start = ((vstart & 0x03FF0000) >> 16) & 0x3FF; - uint32_t end = (vstart & 0x3FF); - uint32_t delta; - if (end > start) - delta = end - start; - else - delta = start - end; - uint32_t scale = (yscale & 0xFFF); - - return (delta * scale) / 0x800; -} - uint64_t rdp_process_commands() { uint64_t interrupt_timer = 0; @@ -431,19 +393,9 @@ uint64_t rdp_process_commands() if (RDP::Op(command) == RDP::Op::SyncFull) { - processor->wait_for_timeline(processor->signal_timeline()); + sync_signal = processor->signal_timeline(); - uint32_t width = viCalculateHorizonalWidth(*gfx_info.VI_H_START_REG, *gfx_info.VI_X_SCALE_REG, *gfx_info.VI_WIDTH_REG); - if (width == 0) - { - width = 320; - } - uint32_t height = viCalculateVerticalHeight(*gfx_info.VI_V_START_REG, *gfx_info.VI_Y_SCALE_REG); - if (height == 0) - { - height = 240; - } - interrupt_timer = width * height * 4; + interrupt_timer = 60000; } cmd_cur += cmd_length; @@ -455,3 +407,8 @@ uint64_t rdp_process_commands() return interrupt_timer; } + +void rdp_full_sync() +{ + processor->wait_for_timeline(sync_signal); +} diff --git a/parallel-rdp/interface.hpp b/parallel-rdp/interface.hpp index b53268e8..1796a285 100644 --- a/parallel-rdp/interface.hpp +++ b/parallel-rdp/interface.hpp @@ -16,11 +16,6 @@ extern "C" uint32_t *DPC_START_REG; uint32_t *DPC_END_REG; uint32_t *DPC_STATUS_REG; - uint32_t *VI_H_START_REG; - uint32_t *VI_V_START_REG; - uint32_t *VI_X_SCALE_REG; - uint32_t *VI_Y_SCALE_REG; - uint32_t *VI_WIDTH_REG; } GFX_INFO; void rdp_init(void *_window, GFX_INFO _gfx_info, bool _upscale, bool _integer_scaling, bool _fullscreen); @@ -28,6 +23,7 @@ extern "C" void rdp_set_vi_register(uint32_t reg, uint32_t value); bool rdp_update_screen(); uint64_t rdp_process_commands(); + void rdp_full_sync(); #ifdef __cplusplus } diff --git a/src/device.rs b/src/device.rs index 50b4f5eb..d639059a 100644 --- a/src/device.rs +++ b/src/device.rs @@ -381,6 +381,7 @@ impl Device { regs_dpc: [0; rdp::DPC_REGS_COUNT as usize], regs_dps: [0; rdp::DPS_REGS_COUNT as usize], wait_frozen: false, + last_status_value: 0, }, mi: mi::Mi { regs: [0; mi::MI_REGS_COUNT as usize], diff --git a/src/device/rdp.rs b/src/device/rdp.rs index 6b04b906..29a01ac1 100644 --- a/src/device/rdp.rs +++ b/src/device/rdp.rs @@ -45,6 +45,7 @@ pub struct Rdp { pub regs_dpc: [u32; DPC_REGS_COUNT as usize], pub regs_dps: [u32; DPS_REGS_COUNT as usize], pub wait_frozen: bool, + pub last_status_value: u32, } pub fn read_regs_dpc( @@ -54,6 +55,15 @@ pub fn read_regs_dpc( ) -> u32 { let reg = (address & 0xFFFF) >> 2; match reg as u32 { + DPC_STATUS_REG => { + let value = + device.rdp.regs_dpc[reg as usize] & (DPC_STATUS_PIPE_BUSY | DPC_STATUS_CMD_BUSY); + if value == device.rdp.last_status_value && value != 0 { + device.rsp.cpu.sync_point = true; + } + device.rdp.last_status_value = value; + device.rdp.regs_dpc[reg as usize] + } DPC_CLOCK_REG => 0xFFFFFF, // needed for JFG DPC_CURRENT_REG => { if device.rdp.wait_frozen { @@ -103,7 +113,8 @@ pub fn write_regs_dpc(device: &mut device::Device, address: u64, value: u32, mas fn run_rdp(device: &mut device::Device) { let timer = ui::video::process_rdp_list(); - device.rdp.regs_dpc[DPC_STATUS_REG as usize] |= DPC_STATUS_START_GCLK | DPC_STATUS_PIPE_BUSY; + device.rdp.regs_dpc[DPC_STATUS_REG as usize] |= + DPC_STATUS_START_GCLK | DPC_STATUS_PIPE_BUSY | DPC_STATUS_CMD_BUSY; if timer != 0 { device::events::create_event( @@ -185,7 +196,10 @@ pub fn init(device: &mut device::Device) { } fn rdp_interrupt_event(device: &mut device::Device) { - device.rdp.regs_dpc[DPC_STATUS_REG as usize] &= !(DPC_STATUS_START_GCLK | DPC_STATUS_PIPE_BUSY); + ui::video::full_sync(); + + device.rdp.regs_dpc[DPC_STATUS_REG as usize] &= + !(DPC_STATUS_START_GCLK | DPC_STATUS_PIPE_BUSY | DPC_STATUS_CMD_BUSY); device::mi::set_rcp_interrupt(device, device::mi::MI_INTR_DP) } diff --git a/src/device/vi.rs b/src/device/vi.rs index 29153175..df277f6f 100644 --- a/src/device/vi.rs +++ b/src/device/vi.rs @@ -5,18 +5,18 @@ use governor::clock::Clock; const VI_STATUS_REG: u32 = 0; //const VI_ORIGIN_REG: u32 = 1; -pub const VI_WIDTH_REG: u32 = 2; +//const VI_WIDTH_REG: u32 = 2; //const VI_V_INTR_REG: u32 = 3; const VI_CURRENT_REG: u32 = 4; //const VI_BURST_REG: u32 = 5; const VI_V_SYNC_REG: u32 = 6; const VI_H_SYNC_REG: u32 = 7; //const VI_LEAP_REG: u32 = 8; -pub const VI_H_START_REG: u32 = 9; -pub const VI_V_START_REG: u32 = 10; +//const VI_H_START_REG: u32 = 9; +//const VI_V_START_REG: u32 = 10; //const VI_V_BURST_REG: u32 = 11; -pub const VI_X_SCALE_REG: u32 = 12; -pub const VI_Y_SCALE_REG: u32 = 13; +//const VI_X_SCALE_REG: u32 = 12; +//const VI_Y_SCALE_REG: u32 = 13; pub const VI_REGS_COUNT: u32 = 14; pub struct Vi { diff --git a/src/ui/video.rs b/src/ui/video.rs index dfa52e58..8704166b 100644 --- a/src/ui/video.rs +++ b/src/ui/video.rs @@ -33,11 +33,6 @@ pub fn init(device: &mut device::Device, fullscreen: bool) { DPC_START_REG: &mut device.rdp.regs_dpc[device::rdp::DPC_START_REG as usize], DPC_END_REG: &mut device.rdp.regs_dpc[device::rdp::DPC_END_REG as usize], DPC_STATUS_REG: &mut device.rdp.regs_dpc[device::rdp::DPC_STATUS_REG as usize], - VI_H_START_REG: &mut device.vi.regs[device::vi::VI_H_START_REG as usize], - VI_V_START_REG: &mut device.vi.regs[device::vi::VI_V_START_REG as usize], - VI_X_SCALE_REG: &mut device.vi.regs[device::vi::VI_X_SCALE_REG as usize], - VI_Y_SCALE_REG: &mut device.vi.regs[device::vi::VI_Y_SCALE_REG as usize], - VI_WIDTH_REG: &mut device.vi.regs[device::vi::VI_WIDTH_REG as usize], }; unsafe { @@ -63,6 +58,10 @@ pub fn update_screen() -> bool { unsafe { rdp_update_screen() } } +pub fn full_sync() { + unsafe { rdp_full_sync() } +} + pub fn set_register(reg: u32, value: u32) { unsafe { rdp_set_vi_register(reg, value);