mirror of
https://github.com/gopher64/gopher64.git
synced 2026-07-11 01:25:20 +02:00
use hashmap for lut (#994)
This commit is contained in:
+2
-2
@@ -310,8 +310,8 @@ impl Device {
|
||||
is_event: false,
|
||||
instrs: [cop0::reserved; 32],
|
||||
instrs2: [cop0::reserved; 32],
|
||||
tlb_lut_w: vec![],
|
||||
tlb_lut_r: vec![],
|
||||
tlb_lut_w: rustc_hash::FxHashMap::default(),
|
||||
tlb_lut_r: rustc_hash::FxHashMap::default(),
|
||||
tlb_entries: [tlb::TlbEntry {
|
||||
mask: 0,
|
||||
vpn2: 0,
|
||||
|
||||
+2
-5
@@ -100,10 +100,8 @@ pub struct Cop0 {
|
||||
pub instrs: [fn(&mut device::Device, u32); 32],
|
||||
#[serde(skip, default = "savestates::default_instructions")]
|
||||
pub instrs2: [fn(&mut device::Device, u32); 32],
|
||||
#[serde(skip)]
|
||||
pub tlb_lut_r: Vec<device::tlb::TlbLut>,
|
||||
#[serde(skip)]
|
||||
pub tlb_lut_w: Vec<device::tlb::TlbLut>,
|
||||
pub tlb_lut_r: rustc_hash::FxHashMap<u64, device::tlb::TlbLut>,
|
||||
pub tlb_lut_w: rustc_hash::FxHashMap<u64, device::tlb::TlbLut>,
|
||||
pub tlb_entries: [device::tlb::TlbEntry; 32],
|
||||
pub is_event: bool,
|
||||
}
|
||||
@@ -371,7 +369,6 @@ pub fn init(device: &mut device::Device) {
|
||||
];
|
||||
|
||||
map_instructions(device);
|
||||
device::tlb::init(device);
|
||||
|
||||
// taken from VR4300 manual
|
||||
device.cpu.cop0.regs[COP0_RANDOM_REG] = 0b00000000000000000000000000011111;
|
||||
|
||||
+39
-46
@@ -30,23 +30,6 @@ pub struct TlbEntry {
|
||||
pub phys_odd: u64,
|
||||
}
|
||||
|
||||
pub fn init(device: &mut device::Device) {
|
||||
device.cpu.cop0.tlb_lut_r.resize(
|
||||
0x100000,
|
||||
device::tlb::TlbLut {
|
||||
address: 0,
|
||||
cached: false,
|
||||
},
|
||||
);
|
||||
device.cpu.cop0.tlb_lut_w.resize(
|
||||
0x100000,
|
||||
device::tlb::TlbLut {
|
||||
address: 0,
|
||||
cached: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
pub fn read(device: &mut device::Device, index: u64) {
|
||||
if index > 31 {
|
||||
return;
|
||||
@@ -166,15 +149,13 @@ fn tlb_unmap(device: &mut device::Device, index: u64) {
|
||||
if e.v_even != 0 {
|
||||
let mut i = e.start_even;
|
||||
while i < e.end_even {
|
||||
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address = 0;
|
||||
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = false;
|
||||
device.cpu.cop0.tlb_lut_r.remove(&(i >> 12));
|
||||
i += 0x1000
|
||||
}
|
||||
if e.d_even != 0 {
|
||||
let mut i = e.start_even;
|
||||
while i < e.end_even {
|
||||
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address = 0;
|
||||
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = false;
|
||||
device.cpu.cop0.tlb_lut_w.remove(&(i >> 12));
|
||||
i += 0x1000
|
||||
}
|
||||
}
|
||||
@@ -183,22 +164,20 @@ fn tlb_unmap(device: &mut device::Device, index: u64) {
|
||||
if e.v_odd != 0 {
|
||||
let mut i = e.start_odd;
|
||||
while i < e.end_odd {
|
||||
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address = 0;
|
||||
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = false;
|
||||
device.cpu.cop0.tlb_lut_r.remove(&(i >> 12));
|
||||
i += 0x1000
|
||||
}
|
||||
if e.d_odd != 0 {
|
||||
let mut i = e.start_odd;
|
||||
while i < e.end_odd {
|
||||
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address = 0;
|
||||
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = false;
|
||||
device.cpu.cop0.tlb_lut_w.remove(&(i >> 12));
|
||||
i += 0x1000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tlb_map(device: &mut device::Device, index: u64) {
|
||||
fn tlb_map(device: &mut device::Device, index: u64) {
|
||||
let e = &device.cpu.cop0.tlb_entries[index as usize];
|
||||
|
||||
if e.v_even != 0
|
||||
@@ -208,17 +187,25 @@ pub fn tlb_map(device: &mut device::Device, index: u64) {
|
||||
{
|
||||
let mut i = e.start_even;
|
||||
while i < e.end_even {
|
||||
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address =
|
||||
0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF);
|
||||
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = e.c_even != 2;
|
||||
device.cpu.cop0.tlb_lut_r.insert(
|
||||
i >> 12,
|
||||
device::tlb::TlbLut {
|
||||
address: 0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF),
|
||||
cached: e.c_even != 2,
|
||||
},
|
||||
);
|
||||
i += 0x1000
|
||||
}
|
||||
if e.d_even != 0 {
|
||||
let mut i = e.start_even;
|
||||
while i < e.end_even {
|
||||
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address =
|
||||
0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF);
|
||||
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = e.c_even != 2;
|
||||
device.cpu.cop0.tlb_lut_w.insert(
|
||||
i >> 12,
|
||||
device::tlb::TlbLut {
|
||||
address: 0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF),
|
||||
cached: e.c_even != 2,
|
||||
},
|
||||
);
|
||||
i += 0x1000
|
||||
}
|
||||
}
|
||||
@@ -231,17 +218,25 @@ pub fn tlb_map(device: &mut device::Device, index: u64) {
|
||||
{
|
||||
let mut i = e.start_odd;
|
||||
while i < e.end_odd {
|
||||
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address =
|
||||
0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF);
|
||||
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = e.c_odd != 2;
|
||||
device.cpu.cop0.tlb_lut_r.insert(
|
||||
i >> 12,
|
||||
device::tlb::TlbLut {
|
||||
address: 0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF),
|
||||
cached: e.c_odd != 2,
|
||||
},
|
||||
);
|
||||
i += 0x1000
|
||||
}
|
||||
if e.d_odd != 0 {
|
||||
let mut i = e.start_odd;
|
||||
while i < e.end_odd {
|
||||
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address =
|
||||
0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF);
|
||||
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = e.c_odd != 2;
|
||||
device.cpu.cop0.tlb_lut_w.insert(
|
||||
i >> 12,
|
||||
device::tlb::TlbLut {
|
||||
address: 0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF),
|
||||
cached: e.c_odd != 2,
|
||||
},
|
||||
);
|
||||
i += 0x1000
|
||||
}
|
||||
}
|
||||
@@ -256,19 +251,17 @@ pub fn get_physical_address(
|
||||
address &= 0xffffffff;
|
||||
|
||||
if access_type == device::memory::AccessType::Write {
|
||||
if device.cpu.cop0.tlb_lut_w[(address >> 12) as usize].address != 0 {
|
||||
if let Some(lut) = device.cpu.cop0.tlb_lut_w.get(&(address >> 12)) {
|
||||
return (
|
||||
(device.cpu.cop0.tlb_lut_w[(address >> 12) as usize].address & 0x1FFFF000)
|
||||
| (address & 0xFFF),
|
||||
device.cpu.cop0.tlb_lut_w[(address >> 12) as usize].cached,
|
||||
(lut.address & 0x1FFFF000) | (address & 0xFFF),
|
||||
lut.cached,
|
||||
false,
|
||||
);
|
||||
}
|
||||
} else if device.cpu.cop0.tlb_lut_r[(address >> 12) as usize].address != 0 {
|
||||
} else if let Some(lut) = device.cpu.cop0.tlb_lut_r.get(&(address >> 12)) {
|
||||
return (
|
||||
(device.cpu.cop0.tlb_lut_r[(address >> 12) as usize].address & 0x1FFFF000)
|
||||
| (address & 0xFFF),
|
||||
device.cpu.cop0.tlb_lut_r[(address >> 12) as usize].cached,
|
||||
(lut.address & 0x1FFFF000) | (address & 0xFFF),
|
||||
lut.cached,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -247,11 +247,6 @@ pub fn load_savestate(device: &mut device::Device, rewind: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
device::tlb::init(device);
|
||||
for i in 0..32 {
|
||||
device::tlb::tlb_map(device, i);
|
||||
}
|
||||
|
||||
device::pif::connect_pif_channels(device);
|
||||
for i in 0..4 {
|
||||
if let Some(handler) = device.pif.channels[i].pak_handler {
|
||||
|
||||
Reference in New Issue
Block a user