@tmustier/pi-nes 0.2.14 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -438,22 +438,22 @@ impl Ppu {
438
438
  // 0x0000 - 0x1FFF is mapped with cartridge's CHR-ROM if exists.
439
439
  // Otherwise load from VRAM.
440
440
 
441
- match address < 0x2000 && rom.has_chr_rom() {
442
- true => rom.load(address as u32),
443
- false => self.vram.load(self.convert_vram_address(address, rom) as u32)
441
+ if address < 0x2000 {
442
+ return rom.load_chr(address as u32);
444
443
  }
444
+ self.vram.load(self.convert_vram_address(address, rom) as u32)
445
445
  }
446
446
 
447
447
  fn store(&mut self, mut address: u16, value: u8, rom: &mut Rom) {
448
448
  address = address & 0x3FFF; // just in case
449
449
 
450
- // 0x0000 - 0x1FFF is mapped with cartridge's CHR-ROM if exists.
451
- // Otherwise store to VRAM.
450
+ // 0x0000 - 0x1FFF is mapped with cartridge CHR (ROM or RAM).
452
451
 
453
- match address < 0x2000 && rom.has_chr_rom() {
454
- true => rom.store(address as u32, value),
455
- false => self.vram.store(self.convert_vram_address(address, rom) as u32, value)
456
- };
452
+ if address < 0x2000 {
453
+ rom.store_chr(address as u32, value);
454
+ return;
455
+ }
456
+ self.vram.store(self.convert_vram_address(address, rom) as u32, value);
457
457
  }
458
458
 
459
459
  fn convert_vram_address(&self, address: u16, rom: &Rom) -> u16 {
@@ -4,6 +4,7 @@ use mapper::{Mapper, MapperFactory};
4
4
  pub struct Rom {
5
5
  header: RomHeader,
6
6
  memory: Memory,
7
+ chr_ram: Option<Memory>,
7
8
  mapper: Box<dyn Mapper>
8
9
  }
9
10
 
@@ -26,9 +27,14 @@ impl Rom {
26
27
  } else {
27
28
  Vec::new()
28
29
  };
30
+ let chr_ram = match header.chr_ram_size_bytes() {
31
+ 0 => None,
32
+ size => Some(Memory::new(vec![0; size])),
33
+ };
29
34
  Rom {
30
35
  header: header,
31
36
  memory: Memory::new(rom_data),
37
+ chr_ram,
32
38
  mapper: mapper
33
39
  }
34
40
  }
@@ -43,21 +49,63 @@ impl Rom {
43
49
  * In general writing control registers in Mapper via .store() switches bank.
44
50
  */
45
51
  pub fn load(&self, address: u32) -> u8 {
46
- let mut address_in_rom = 0 as u32;
47
52
  if address < 0x2000 {
48
- // load from character rom
49
- address_in_rom += self.header.prg_rom_bank_num() as u32 * 0x4000;
50
- address_in_rom += self.mapper.map_for_chr_rom(address);
51
- } else {
52
- address_in_rom += self.mapper.map(address);
53
+ return self.load_chr(address);
54
+ }
55
+ self.memory.load(self.mapper.map(address))
56
+ }
57
+
58
+ pub fn load_chr(&self, address: u32) -> u8 {
59
+ let mapped = self.map_chr_address(address);
60
+ if let Some(chr_ram) = &self.chr_ram {
61
+ return chr_ram.load(mapped);
62
+ }
63
+ let offset = self.prg_rom_size() + mapped;
64
+ self.memory.load(offset)
65
+ }
66
+
67
+ pub fn store_chr(&mut self, address: u32, value: u8) {
68
+ let size = match self.chr_ram.as_ref() {
69
+ Some(ram) => ram.capacity(),
70
+ None => return,
71
+ };
72
+ if size == 0 {
73
+ return;
74
+ }
75
+ let mapped = self.mapper.map_for_chr_rom(address) % size;
76
+ if let Some(chr_ram) = self.chr_ram.as_mut() {
77
+ chr_ram.store(mapped, value);
53
78
  }
54
- self.memory.load(address_in_rom)
55
79
  }
56
80
 
57
81
  pub fn load_without_mapping(&self, address: u32) -> u8 {
58
82
  self.memory.load(address)
59
83
  }
60
84
 
85
+ fn prg_rom_size(&self) -> u32 {
86
+ self.header.prg_rom_bank_num() as u32 * 0x4000
87
+ }
88
+
89
+ fn chr_rom_size(&self) -> u32 {
90
+ self.header.chr_rom_bank_num() as u32 * 0x2000
91
+ }
92
+
93
+ fn chr_ram_size(&self) -> u32 {
94
+ self.chr_ram.as_ref().map_or(0, |ram| ram.capacity())
95
+ }
96
+
97
+ fn map_chr_address(&self, address: u32) -> u32 {
98
+ let size = if self.chr_ram.is_some() {
99
+ self.chr_ram_size()
100
+ } else {
101
+ self.chr_rom_size()
102
+ };
103
+ if size == 0 {
104
+ return 0;
105
+ }
106
+ self.mapper.map_for_chr_rom(address) % size
107
+ }
108
+
61
109
  /**
62
110
  * In general writing with ROM address space updates control registers in Mapper.
63
111
  */
@@ -141,6 +189,13 @@ impl RomHeader {
141
189
  self.chr_rom_bank_num() > 0
142
190
  }
143
191
 
192
+ fn chr_ram_size_bytes(&self) -> usize {
193
+ if self.has_chr_rom() {
194
+ return 0;
195
+ }
196
+ 0x2000
197
+ }
198
+
144
199
  fn control_byte1(&self) -> u8 {
145
200
  self.load(6)
146
201
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-nes",
3
- "version": "0.2.14",
3
+ "version": "0.2.15",
4
4
  "description": "NES emulator extension for pi",
5
5
  "keywords": [
6
6
  "pi-package",