diff --git a/src/device.rs b/src/device.rs index abfd524..67b0ff5 100644 --- a/src/device.rs +++ b/src/device.rs @@ -323,6 +323,7 @@ impl Device { rdram: rdram::Rdram { mem: vec![], size: 0x800000, + regs: [[0; rdram::RDRAM_REGS_COUNT as usize]; 4], }, rsp: rsp_interface::Rsp { cpu: rsp_cpu::Cpu { @@ -403,6 +404,7 @@ impl Device { }, ri: ri::Ri { regs: [0; ri::RI_REGS_COUNT as usize], + ram_init: false, }, vi: vi::Vi { regs: [0; vi::VI_REGS_COUNT as usize], diff --git a/src/device/rdram.rs b/src/device/rdram.rs index 83bb125..25d7c2b 100644 --- a/src/device/rdram.rs +++ b/src/device/rdram.rs @@ -1,11 +1,24 @@ use crate::device; use std::alloc::{alloc_zeroed, Layout}; +//const RDRAM_CONFIG_REG: u32 = 0; +//const RDRAM_DEVICE_ID_REG: u32 = 1; +//const RDRAM_DELAY_REG: u32 = 2; +const RDRAM_MODE_REG: u32 = 3; +//const RDRAM_REF_INTERVAL_REG: u32 = 4; +//const RDRAM_REF_ROW_REG: u32 = 5; +//const RDRAM_RAS_INTERVAL_REG: u32 = 6; +//const RDRAM_MIN_INTERVAL_REG: u32 = 7; +//const RDRAM_ADDR_SELECT_REG: u32 = 8; +//const RDRAM_DEVICE_MANUF_REG: u32 = 9; +pub const RDRAM_REGS_COUNT: u32 = 10; + pub const RDRAM_MASK: usize = 0xFFFFFF; pub struct Rdram { pub mem: Vec, pub size: u32, + pub regs: [[u32; RDRAM_REGS_COUNT as usize]; 4], } pub fn read_mem_fast( @@ -56,16 +69,26 @@ pub fn write_mem(device: &mut device::Device, address: u64, value: u32, mask: u3 } pub fn read_regs( - _device: &mut device::Device, + device: &mut device::Device, address: u64, _access_size: device::memory::AccessSize, ) -> u32 { - println!("Warning: read from RDRAM reg {:#x}", address); - 0 + let chip_id = address >> 13 & 3; + let reg = (address & 0x3FF) >> 2; + match reg as u32 { + RDRAM_MODE_REG => device.pi.regs[reg as usize] ^ 0xc0c0c0c0, + _ => device.rdram.regs[chip_id as usize][reg as usize], + } } -pub fn write_regs(_device: &mut device::Device, _address: u64, _value: u32, _mask: u32) { - panic!("rdram write reg"); +pub fn write_regs(device: &mut device::Device, address: u64, value: u32, mask: u32) { + let chip_id = address >> 13 & 3; + let reg = (address & 0x3FF) >> 2; + device::memory::masked_write_32( + &mut device.rdram.regs[chip_id as usize][reg as usize], + value, + mask, + ) } pub fn init(device: &mut device::Device) { @@ -79,6 +102,11 @@ pub fn init(device: &mut device::Device) { // hack, skip RDRAM initialization device.rdram.mem[device.cart.rdram_size_offset..device.cart.rdram_size_offset + 4] .copy_from_slice(&device.rdram.size.to_ne_bytes()); + + device.ri.regs[device::ri::RI_MODE_REG as usize] = 0x0e; + device.ri.regs[device::ri::RI_CONFIG_REG as usize] = 0x40; + device.ri.regs[device::ri::RI_SELECT_REG as usize] = 0x14; + device.ri.regs[device::ri::RI_REFRESH_REG as usize] = 0x00063634; } pub fn rdram_calculate_cycles(length: u64) -> u64 { diff --git a/src/device/ri.rs b/src/device/ri.rs index bfc1844..55ae22b 100644 --- a/src/device/ri.rs +++ b/src/device/ri.rs @@ -1,10 +1,10 @@ use crate::device; -//const RI_MODE_REG: u32 = 0; -//const RI_CONFIG_REG: u32 = 1; +pub const RI_MODE_REG: u32 = 0; +pub const RI_CONFIG_REG: u32 = 1; //const RI_CURRENT_LOAD_REG: u32 = 2; -const RI_SELECT_REG: u32 = 3; -//const RI_REFRESH_REG: u32 = 4; +pub const RI_SELECT_REG: u32 = 3; +pub const RI_REFRESH_REG: u32 = 4; //const RI_LATENCY_REG: u32 = 5; //const RI_ERROR_REG: u32 = 6; //const RI_WERROR_REG: u32 = 7; @@ -12,6 +12,7 @@ pub const RI_REGS_COUNT: u32 = 8; pub struct Ri { pub regs: [u32; RI_REGS_COUNT as usize], + pub ram_init: bool, } pub fn read_regs( @@ -19,8 +20,9 @@ pub fn read_regs( address: u64, _access_size: device::memory::AccessSize, ) -> u32 { - if ((address & 0xFFFF) >> 2) as u32 == RI_SELECT_REG { - return 0x14; // hack, skip RDRAM initialization + if ((address & 0xFFFF) >> 2) as u32 == RI_SELECT_REG && !device.ri.ram_init { + device::cop0::add_cycles(device, device.cpu.clock_rate / 2); // hack, simulate RDRAM initialization + device.ri.ram_init = true; } device.ri.regs[((address & 0xFFFF) >> 2) as usize] }