1mod dma;
2mod expansion_regions;
3pub(crate) mod interrupts;
4mod memory_control;
5mod ram;
6
7use std::fs::File;
8use std::io::{Read, Seek, SeekFrom};
9use std::path::Path;
10use std::sync::Arc;
11
12use crate::gpu::{Device, Queue};
13use byteorder::{ByteOrder, LittleEndian, ReadBytesExt};
14
15use crate::cdrom::Cdrom;
16use crate::controller_mem_card::ControllerAndMemoryCard;
17use crate::cpu::CpuBusProvider;
18use crate::gpu::Gpu;
19use crate::mdec::Mdec;
20use crate::spu::Spu;
21use crate::timers::Timers;
22use crate::{PsxConfig, PsxError};
23
24use dma::Dma;
25use expansion_regions::{ExpansionRegion1, ExpansionRegion2};
26use interrupts::Interrupts;
27use memory_control::{CacheControl, MemoryControl1, MemoryControl2};
28use ram::{MainRam, Scratchpad};
29
30pub type Result<T, E = String> = std::result::Result<T, E>;
31
32pub trait BusLine {
37 fn read_u32(&mut self, addr: u32) -> Result<u32> {
38 Err(format!(
39 "{}: u32 read from {:08X}",
40 std::any::type_name::<Self>(),
41 addr
42 ))
43 }
44
45 fn write_u32(&mut self, addr: u32, _data: u32) -> Result<()> {
46 Err(format!(
47 "{}: u32 write to {:08X}",
48 std::any::type_name::<Self>(),
49 addr
50 ))
51 }
52
53 fn read_u16(&mut self, addr: u32) -> Result<u16> {
54 Err(format!(
55 "{}: u16 read from {:08X}",
56 std::any::type_name::<Self>(),
57 addr
58 ))
59 }
60 fn write_u16(&mut self, addr: u32, _data: u16) -> Result<()> {
61 Err(format!(
62 "{}: u16 write to {:08X}",
63 std::any::type_name::<Self>(),
64 addr
65 ))
66 }
67
68 fn read_u8(&mut self, addr: u32) -> Result<u8> {
69 Err(format!(
70 "{}: u8 read from {:08X}",
71 std::any::type_name::<Self>(),
72 addr
73 ))
74 }
75 fn write_u8(&mut self, addr: u32, _data: u8) -> Result<()> {
76 Err(format!(
77 "{}: u8 write to {:08X}",
78 std::any::type_name::<Self>(),
79 addr
80 ))
81 }
82}
83
84pub struct Bios {
85 data: Vec<u8>,
86}
87
88impl Bios {
89 fn write_u32(&mut self, addr: u32, data: u32) {
90 let index = (addr & 0xFFFFF) as usize;
91
92 LittleEndian::write_u32(&mut self.data[index..index + 4], data)
93 }
94
95 fn apply_patches(&mut self) {
96 if self.read_u32(0x6f0c).unwrap() == 0x3C01A001
100 && self.read_u32(0x6f14).unwrap() == 0xAC20B9B0
101 {
102 self.write_u32(0x6f0c, 0x34010001);
103 self.write_u32(0x6f14, 0xAF81A9C0);
104 }
105 if self.read_u32(0x14330).unwrap() == 0x92200000
130 && self.read_u32(0x14334).unwrap() == 0x10000047
131 && self.read_u32(0x14338).unwrap() == 0x8fae0040
132 {
133 self.write_u32(0x14330, 0x00000000);
134 self.write_u32(0x14334, 0x10000006);
135 self.write_u32(0x14338, 0x00000000);
136 }
137 }
138}
139
140impl Bios {
141 pub fn from_file<P: AsRef<Path>>(bios_file_path: P) -> Result<Self, PsxError> {
143 let mut data = Vec::new();
144
145 let mut file = File::open(bios_file_path).map_err(|_| PsxError::CouldNotLoadBios)?;
146
147 file.read_to_end(&mut data)
148 .map_err(|_| PsxError::CouldNotLoadBios)?;
149
150 let mut s = Self { data };
151
152 s.apply_patches();
153
154 Ok(s)
155 }
156
157 pub fn read_u32(&self, addr: u32) -> Result<u32> {
158 let index = (addr & 0xFFFFF) as usize;
159
160 Ok(LittleEndian::read_u32(&self.data[index..index + 4]))
161 }
162
163 pub fn read_u16(&self, addr: u32) -> Result<u16> {
164 let index = (addr & 0xFFFFF) as usize;
165
166 Ok(LittleEndian::read_u16(&self.data[index..index + 4]))
167 }
168
169 pub fn read_u8(&self, addr: u32) -> Result<u8> {
170 let index = (addr & 0xFFFFF) as usize;
171
172 Ok(self.data[index])
173 }
174}
175
176struct DmaBus {
191 pub main_ram: MainRam,
192 pub cdrom: Cdrom,
193 pub gpu: Gpu,
194 pub mdec: Mdec,
195 pub spu: Spu,
196}
197
198pub struct CpuBus {
199 bios: Bios,
200 mem_ctrl_1: MemoryControl1,
201 mem_ctrl_2: MemoryControl2,
202 cache_control: CacheControl,
203 interrupts: Interrupts,
204 controller_mem_card: ControllerAndMemoryCard,
205
206 expansion_region_1: ExpansionRegion1,
207 expansion_region_2: ExpansionRegion2,
208
209 timers: Timers,
210
211 dma: Dma,
212 dma_bus: DmaBus,
213
214 scratchpad: Scratchpad,
215 config: PsxConfig,
216}
217
218impl CpuBus {
219 pub fn new<DiskPath: AsRef<Path>>(
220 bios: Bios,
221 disk_file: Option<DiskPath>,
222 config: PsxConfig,
223 device: Arc<Device>,
224 queue: Arc<Queue>,
225 ) -> Result<Self, PsxError> {
226 let mut s = Self {
227 bios,
228 mem_ctrl_1: MemoryControl1::default(),
229 mem_ctrl_2: MemoryControl2::default(),
230 cache_control: CacheControl::default(),
231 interrupts: Interrupts::default(),
232 controller_mem_card: ControllerAndMemoryCard::default(),
233
234 expansion_region_1: ExpansionRegion1::default(),
235 expansion_region_2: ExpansionRegion2::new(config),
236 dma: Dma::default(),
237
238 timers: Timers::default(),
239
240 dma_bus: DmaBus {
241 cdrom: Cdrom::default(),
242 gpu: Gpu::new(device, queue),
243 main_ram: MainRam::default(),
244 mdec: Mdec::default(),
245 spu: Spu::default(),
246 },
247
248 scratchpad: Scratchpad::default(),
249 config,
250 };
251
252 if let Some(disk_file) = disk_file {
254 let path = disk_file.as_ref().to_owned();
255 match path
257 .extension()
258 .unwrap()
259 .to_str()
260 .unwrap()
261 .to_ascii_lowercase()
262 .as_str()
263 {
264 "cue" => s.dma_bus.cdrom.set_cue_file(disk_file)?,
265 _ => {
266 return Err(PsxError::DiskTypeNotSupported);
267 }
268 }
269 }
270
271 Ok(s)
272 }
273
274 pub fn reset(&mut self) {
275 self.mem_ctrl_1 = MemoryControl1::default();
276 self.mem_ctrl_2 = MemoryControl2::default();
277 self.cache_control = CacheControl::default();
278 self.interrupts = Interrupts::default();
279 self.controller_mem_card = ControllerAndMemoryCard::default();
280
281 self.expansion_region_1 = ExpansionRegion1::default();
282 self.expansion_region_2 = ExpansionRegion2::new(self.config);
283 self.dma = Dma::default();
284
285 self.timers = Timers::default();
286
287 self.dma_bus.cdrom.reset();
288 self.dma_bus.gpu.reset();
289 self.dma_bus.main_ram = MainRam::default();
290 self.dma_bus.mdec = Mdec::default();
291 self.dma_bus.spu = Spu::default();
292
293 self.scratchpad = Scratchpad::default();
294 }
295
296 pub fn gpu(&self) -> &Gpu {
297 &self.dma_bus.gpu
298 }
299
300 pub fn gpu_mut(&mut self) -> &mut Gpu {
301 &mut self.dma_bus.gpu
302 }
303
304 pub fn controller_mem_card_mut(&mut self) -> &mut ControllerAndMemoryCard {
305 &mut self.controller_mem_card
306 }
307
308 pub fn spu(&self) -> &Spu {
309 &self.dma_bus.spu
310 }
311
312 pub fn spu_mut(&mut self) -> &mut Spu {
313 &mut self.dma_bus.spu
314 }
315
316 pub fn cdrom_mut(&mut self) -> &mut Cdrom {
317 &mut self.dma_bus.cdrom
318 }
319}
320
321impl CpuBus {
322 pub fn load_exe_in_memory<P: AsRef<Path>>(&mut self, exe_file_path: P) -> (u32, u32, u32) {
326 let mut file = File::open(exe_file_path).unwrap();
327 let mut magic = [0; 8];
328 let mut data = Vec::new();
329
330 file.read_exact(&mut magic).unwrap();
331 assert!(&magic == b"PS-X EXE");
332 assert!(file.read_u64::<LittleEndian>().unwrap() == 0);
334
335 let initial_pc = file.read_u32::<LittleEndian>().unwrap();
336 let initial_gp = file.read_u32::<LittleEndian>().unwrap();
337 let destination = file.read_u32::<LittleEndian>().unwrap();
338 let file_size = file.read_u32::<LittleEndian>().unwrap();
339 let _data_section_start = file.read_u32::<LittleEndian>().unwrap();
340 let _data_section_size = file.read_u32::<LittleEndian>().unwrap();
341 let _bss_section_start = file.read_u32::<LittleEndian>().unwrap();
342 let _bss_section_size = file.read_u32::<LittleEndian>().unwrap();
343 let mut initial_sp_fp = file.read_u32::<LittleEndian>().unwrap();
344 initial_sp_fp += file.read_u32::<LittleEndian>().unwrap();
345 file.seek(SeekFrom::Start(0x800)).unwrap();
347
348 file.read_to_end(&mut data).unwrap();
349
350 assert!(data.len() == file_size as usize);
351
352 self.dma_bus
354 .main_ram
355 .put_at_address(&data, destination & 0x1FFFFF);
356
357 (initial_pc, initial_gp, initial_sp_fp)
358 }
359
360 pub fn clock_dma(&mut self) -> u32 {
363 self.dma.clock_dma(&mut self.dma_bus, &mut self.interrupts)
364 }
365
366 pub fn clock_components(&mut self, cpu_cycles: u32) {
367 let (dot_clocks, hblank_clock) = self.dma_bus.gpu.clock(&mut self.interrupts, cpu_cycles);
368
369 self.dma_bus.spu.clock(&mut self.interrupts, cpu_cycles);
370
371 self.controller_mem_card
373 .clock(&mut self.interrupts, cpu_cycles);
374
375 self.dma_bus
377 .cdrom
378 .clock(&mut self.interrupts, &mut self.dma_bus.spu, cpu_cycles);
379
380 self.timers.clock_from_system(cpu_cycles);
382 if hblank_clock {
383 self.timers.clock_from_hblank();
384 }
385 self.timers.clock_from_gpu_dot(dot_clocks);
386 self.timers.handle_interrupts(&mut self.interrupts);
388 }
389
390 fn map_address(&self, addr: u32) -> Result<u32> {
393 let region = addr >> 29;
394 const MASK_512M: u32 = 0x1FFFFFFF;
395
396 match region {
397 0 => Ok(addr & MASK_512M),
399 1..=3 => Err(String::from("Accessing bottom 1.5G of KUSEG")),
400 4 => Ok(addr & MASK_512M),
402 5 => {
404 if (0xBF800000..0xBF801000).contains(&addr) {
405 Err(String::from("Cannot access scratchpad from KSEG1"))
406 } else {
407 Ok(addr & MASK_512M)
408 }
409 }
410 7 if addr >= 0xFFFE0000 => Ok(addr), 6 | 7 => Err(String::from(
413 "KSEG2 has only the cache control registers at 0xFFFE0000",
414 )),
415 _ => unreachable!(),
416 }
417 }
418}
419
420impl BusLine for CpuBus {
421 fn read_u32(&mut self, addr: u32) -> Result<u32> {
422 assert!(addr % 4 == 0, "unalligned u32 read");
423 let addr = self.map_address(addr)?;
424
425 match addr {
426 0x00000000..=0x007FFFFF => self.dma_bus.main_ram.read_u32(addr & 0x1FFFFF),
428 0x1FC00000..=0x1FC80000 => self.bios.read_u32(addr),
429 0x1F800000..=0x1F8003FF => self.scratchpad.read_u32(addr & 0x3FF),
430 0x1F801000..=0x1F801020 => self.mem_ctrl_1.read_u32(addr),
431 0x1F801044..=0x1F80104F => self.controller_mem_card.read_u32(addr & 0xF),
432 0x1F801060 => self.mem_ctrl_2.read_u32(addr),
433 0x1F801070..=0x1F801077 => self.interrupts.read_u32(addr & 0xF),
434 0x1F801080..=0x1F8010FC => self.dma.read_u32(addr & 0xFF),
435 0x1F801100..=0x1F80112F => self.timers.read_u32(addr & 0xFF),
436 0x1F801810..=0x1F801814 => self.dma_bus.gpu.read_u32(addr & 0xF),
437 0x1F801820..=0x1F801824 => self.dma_bus.mdec.read_u32(addr & 0xF),
438 0x1F801C00..=0x1F801FFC => self.dma_bus.spu.read_u32(addr & 0x3FF),
439 0x1F802000..=0x1F80208F => self.expansion_region_2.read_u32(addr & 0xFF),
440 0xFFFE0130 => self.cache_control.read_u32(addr),
441 _ => Err(format!("MainBus: u32 read from {:08X}", addr)),
442 }
443 }
444
445 fn write_u32(&mut self, addr: u32, data: u32) -> Result<()> {
446 assert!(addr % 4 == 0, "unalligned u32 write");
447 let addr = self.map_address(addr)?;
448
449 match addr {
450 0x00000000..=0x007FFFFF => self.dma_bus.main_ram.write_u32(addr & 0x1FFFFF, data),
451 0x1F800000..=0x1F8003FF => self.scratchpad.write_u32(addr & 0x3FF, data),
452 0x1F801000..=0x1F801020 => self.mem_ctrl_1.write_u32(addr, data),
453 0x1F801060 => self.mem_ctrl_2.write_u32(addr, data),
454 0x1F801070..=0x1F801077 => self.interrupts.write_u32(addr & 0xF, data),
455 0x1F801080..=0x1F8010FC => self.dma.write_u32(addr & 0xFF, data),
456 0x1F801100..=0x1F80112F => self.timers.write_u32(addr & 0xFF, data),
457 0x1F801810..=0x1F801814 => self.dma_bus.gpu.write_u32(addr & 0xF, data),
458 0x1F801820..=0x1F801824 => self.dma_bus.mdec.write_u32(addr & 0xF, data),
459 0x1F801C00..=0x1F801FFC => self.dma_bus.spu.write_u32(addr & 0x3FF, data),
460 0x1F802000..=0x1F80208F => self.expansion_region_2.write_u32(addr & 0xFF, data),
461 0xFFFE0130 => self.cache_control.write_u32(addr, data),
462 _ => Err(format!("MainBus: u32 write to {:08X}", addr)),
463 }
464 }
465
466 fn read_u16(&mut self, addr: u32) -> Result<u16> {
467 assert!(addr % 2 == 0, "unalligned u16 read");
468 let addr = self.map_address(addr)?;
469
470 match addr {
471 0x00000000..=0x007FFFFF => self.dma_bus.main_ram.read_u16(addr & 0x1FFFFF),
472 0x1F800000..=0x1F8003FF => self.scratchpad.read_u16(addr & 0x3FF),
473 0x1F801044..=0x1F80104F => self.controller_mem_card.read_u16(addr & 0xF),
474 0x1F801070..=0x1F801077 => self.interrupts.read_u16(addr & 0xF),
475 0x1F801100..=0x1F80112F => self.timers.read_u16(addr & 0xFF),
476 0x1F801C00..=0x1F801FFC => self.dma_bus.spu.read_u16(addr & 0x3FF),
477 0x1FC00000..=0x1FC80000 => self.bios.read_u16(addr),
478 0x1F802000..=0x1F80208F => self.expansion_region_2.read_u16(addr & 0xFF),
479 _ => Err(format!("u16 read from {:08X}", addr)),
480 }
481 }
482
483 fn write_u16(&mut self, addr: u32, data: u16) -> Result<()> {
484 assert!(addr % 2 == 0, "unalligned u16 write");
485 let addr = self.map_address(addr)?;
486
487 match addr {
488 0x00000000..=0x007FFFFF => self.dma_bus.main_ram.write_u16(addr & 0x1FFFFF, data),
489 0x1F800000..=0x1F8003FF => self.scratchpad.write_u16(addr & 0x3FF, data),
490 0x1F801048..=0x1F80104F => self.controller_mem_card.write_u16(addr & 0xF, data),
491 0x1F801070..=0x1F801077 => self.interrupts.write_u16(addr & 0xF, data),
492 0x1F801100..=0x1F80112F => self.timers.write_u16(addr & 0xFF, data),
493 0x1F801C00..=0x1F801FFC => self.dma_bus.spu.write_u16(addr & 0x3FF, data),
494 0x1F802000..=0x1F80208F => self.expansion_region_2.write_u16(addr & 0xFF, data),
495 _ => Err(format!("u16 write to {:08X}", addr)),
496 }
497 }
498 fn read_u8(&mut self, addr: u32) -> Result<u8> {
499 let addr = self.map_address(addr)?;
500
501 match addr {
502 0x00000000..=0x007FFFFF => self.dma_bus.main_ram.read_u8(addr & 0x1FFFFF),
503 0x1F800000..=0x1F8003FF => self.scratchpad.read_u8(addr & 0x3FF),
504 0x1F801040 => self.controller_mem_card.read_u8(addr & 0xF),
505 0x1F000000..=0x1F080000 => self.expansion_region_1.read_u8(addr & 0xFFFFF),
506 0x1F801080..=0x1F8010FF => self.dma.read_u8(addr & 0xFF),
507 0x1F801800..=0x1F801803 => self.dma_bus.cdrom.read_u8(addr & 3),
508 0x1F802000..=0x1F80208F => self.expansion_region_2.read_u8(addr & 0xFF),
509 0x1FC00000..=0x1FC80000 => self.bios.read_u8(addr),
510 _ => Err(format!("u8 read from {:08X}", addr)),
511 }
512 }
513
514 fn write_u8(&mut self, addr: u32, data: u8) -> Result<()> {
515 let addr = self.map_address(addr)?;
516
517 match addr {
518 0x00000000..=0x007FFFFF => self.dma_bus.main_ram.write_u8(addr & 0x1FFFFF, data),
519 0x1F800000..=0x1F8003FF => self.scratchpad.write_u8(addr & 0x3FF, data),
520 0x1F801040 => self.controller_mem_card.write_u8(addr & 0xF, data),
521 0x1F000000..=0x1F080000 => self.expansion_region_1.write_u8(addr & 0xFFFFF, data),
522 0x1F801080..=0x1F8010FF => self.dma.write_u8(addr & 0xFF, data),
523 0x1F801800..=0x1F801803 => self.dma_bus.cdrom.write_u8(addr & 3, data),
524 0x1F802000..=0x1F80208F => self.expansion_region_2.write_u8(addr & 0xFF, data),
525 _ => Err(format!("u8 write to {:08X}", addr)),
526 }
527 }
528}
529
530impl CpuBusProvider for CpuBus {
531 fn pending_interrupts(&self) -> bool {
532 self.interrupts.pending_interrupts()
533 }
534
535 fn should_run_dma(&self) -> bool {
536 self.dma.needs_to_run()
537 }
538}