diff --git a/.gitignore b/.gitignore index ea8c4bf..4bbd3db 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/roms \ No newline at end of file diff --git a/src/cpu.rs b/src/cpu.rs index b950bc9..a6beaa3 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -92,6 +92,13 @@ impl CPU { } } + pub fn new_hle() -> Self { + Self { + registers: CPURegisters::new_hle(), + cp0: CP0Registers::new_hle(), + } + } + pub fn fetch_opcode(address: i64, mmu: &MMU) -> u32 { let data = mmu.read_virtual(address, 4); let opcode = ((data[0] as u32) << 24) | ((data[1] as u32) << 16) | ((data[2] as u32) << 8) | ((data[3] as u32) << 8); diff --git a/src/emulator.rs b/src/emulator.rs new file mode 100644 index 0000000..8065d99 --- /dev/null +++ b/src/emulator.rs @@ -0,0 +1,27 @@ +use crate::mmu::MMU; +use crate::cpu::CPU; + +pub struct Emulator { + cpu: CPU, + mmu: MMU, +} + +impl Emulator { + pub fn new() -> Self { + Self { + cpu: CPU::new(), + mmu: MMU::new(), + } + } + + pub fn new_hle() -> Self { + Self { + cpu: CPU::new_hle(), + mmu: MMU::new_hle(), + } + } + + pub fn tick(&mut self) { + self.cpu.fetch_and_exec_opcode(&mut self.mmu); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index ade4a87..ecfb481 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,3 +3,4 @@ pub mod cpu; pub mod mmu; pub mod rom; pub mod rdram; +pub mod emulator; diff --git a/src/mmu.rs b/src/mmu.rs index aabd2b5..2f37311 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -62,6 +62,22 @@ impl MMU { } } + pub fn new_hle() -> Self { + let mut mmu = Self::new(); + // Skip IPL1 and IPL2 + for i in 0..0x1000 { + let byte = mmu.read_virtual(0x10001000 + i, 1); + mmu.write_virtual(0x00001000 + i, vec![byte]); + } + // Skip IPL3 + for i in 0..0x100000 { + let byte = mmu.read_physical_byte(0x10001000 + i); + mmu.write_physical_byte(0x00001000 + i, byte); + } + + mmu + } + pub fn convert(address: i64) -> i64 { if KUSEG.contains(&address) { return address - KUSEG.min().unwrap(); diff --git a/src/registers.rs b/src/registers.rs index 603b36c..5e2b480 100644 --- a/src/registers.rs +++ b/src/registers.rs @@ -79,6 +79,21 @@ impl CPURegisters { } } + pub fn new_hle() -> Self { + let mut registers = Self::new(); + registers.set_by_name("t3", 0xFFFFFFFFA4000040_u64 as i64); + registers.set_by_name("s4", 0x0000000000000001); + registers.set_by_name("s6", 0x000000000000003F); + registers.set_by_name("sp", 0xFFFFFFFFA4001FF0_u64 as i64); + + registers.set_program_counter(0x80001000); + registers.set_next_program_counter(0x80001000 + 4); + /* registers.set_program_counter(0xA4000040); + registers.set_next_program_counter(0xA4000040 + 4); */ + + registers + } + pub fn set_load_link(&mut self, val: bool) { self.load_link = val; } @@ -238,6 +253,16 @@ impl CP0Registers { } } + pub fn new_hle() -> Self { + let mut cp0 = Self::new(); + cp0.set_by_name_32("random", 0x0000001F); + cp0.set_by_name_32("status", 0x70400004); + cp0.set_by_name_32("PRId", 0x00000B00); + cp0.set_by_name_32("config", 0x0006E463); + + cp0 + } + fn find_index(name: &'static str) -> usize { CP0_REGISTER_NAMES.iter().position(|v| *v == name).unwrap() }