diff --git a/src/gb.rs b/src/gb.rs index 0f9b1613b7951c8adceb9b5a850523667c95e0c0..3d5047f3cc889c6e369cbe1d800f24298a4d7acd 100644 --- a/src/gb.rs +++ b/src/gb.rs @@ -520,7 +520,7 @@ impl GameBoy { match self.mode() { GameBoyMode::Dmg => self.load_dmg(boot), GameBoyMode::Cgb => self.load_cgb(boot), - GameBoyMode::Sgb => todo!(), + GameBoyMode::Sgb => unimplemented!(), } } diff --git a/src/ppu.rs b/src/ppu.rs index 8686cc96b8f0ed3298d8ef75e763a08e92df6860..43234b926ee55ad2b2f64237b4587c8e1c713f09 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -1015,10 +1015,35 @@ impl Ppu { &self.vram } + pub fn vram_dmg(&self) -> &[u8] { + &self.vram[0..VRAM_SIZE_DMG] + } + + pub fn vram_cgb(&self) -> &[u8] { + &self.vram[0..VRAM_SIZE_CGB] + } + + pub fn vram_device(&self) -> &[u8] { + match self.gb_mode { + GameBoyMode::Dmg => self.vram_dmg(), + GameBoyMode::Cgb => self.vram_cgb(), + GameBoyMode::Sgb => self.vram_dmg(), + } + } + + pub fn set_vram(&mut self, value: &[u8]) { + self.vram[0..value.len()].copy_from_slice(value); + self.update_vram(); + } + pub fn hram(&self) -> &[u8; HRAM_SIZE] { &self.hram } + pub fn set_hram(&mut self, value: [u8; HRAM_SIZE]) { + self.hram = value; + } + pub fn tiles(&self) -> &[Tile; TILE_COUNT] { &self.tiles } @@ -1134,6 +1159,28 @@ impl Ppu { println!("{}", self.tiles[tile_index]); } + /// Updates the internal PPU state (calculated values) according + /// to the VRAM values, this should be called whenever the VRAM + /// is replaced. + pub fn update_vram(&mut self) { + let vram_banks = if self.gb_mode == GameBoyMode::Cgb { + 2u16 + } else { + 1u16 + }; + for vram_bank in 0..vram_banks { + let vram_offset = vram_bank * 0x2000; + for addr in 0x8000..=0x9fff { + let value = self.vram[(vram_offset + (addr & 0x1fff)) as usize]; + if addr < 0x9800 { + self.update_tile(addr, value); + } else if vram_bank == 0x1 { + self.update_bg_map_attrs(addr, value); + } + } + } + } + /// Updates the tile structure with the value that has /// just been written to a location on the VRAM associated /// with tiles. @@ -1843,11 +1890,10 @@ impl Ppu { for index in 0..2 { let palette = &mut palettes[index]; let palette_color = &palettes_color[index]; - - for palette_index in (0..palette.len()).step_by(8) { + for palette_index in 0..palette.len() { Self::compute_color_palette( - &mut palette[palette_index / 8], - &palette_color[palette_index..palette_index + 8] + &mut palette[palette_index], + &palette_color[palette_index * 8..(palette_index + 1) * 8] .try_into() .unwrap(), ); @@ -1860,7 +1906,7 @@ impl Ppu { /// represent the 4 colors of the palette in the RGB555 format. fn compute_color_palette(palette: &mut Palette, palette_color: &[u8; 8]) { for color_index in 0..palette.len() { - palette[color_index as usize] = Self::rgb555_to_rgb888( + palette[color_index] = Self::rgb555_to_rgb888( palette_color[color_index * 2], palette_color[color_index * 2 + 1], ); diff --git a/src/state.rs b/src/state.rs index 58b8d70d218ad15de44ad54ef2458e7b28aaf301..9e2f968e4673c42fe77d4f7fb634bbc1ff054e44 100644 --- a/src/state.rs +++ b/src/state.rs @@ -765,7 +765,7 @@ impl State for BeesCore { gb.mmu().read_many(0xff00, 128).try_into().unwrap(), ); core.ram.fill_buffer(gb.mmu().ram()); - core.vram.fill_buffer(&gb.mmu().read_many(0x8000, 0x2000)); + core.vram.fill_buffer(gb.ppu().vram_device()); core.mbc_ram.fill_buffer(gb.rom_i().ram_data()); core.oam.fill_buffer(&gb.mmu().read_many(0xfe00, 0x00a0)); core.hram.fill_buffer(&gb.mmu().read_many(0xff80, 0x007f)); @@ -792,7 +792,7 @@ impl State for BeesCore { gb.mmu().write_many(0xff00, &self.io_registers); gb.mmu().set_ram(self.ram.buffer.to_vec()); - gb.mmu().write_many(0x8000, &self.vram.buffer); + gb.ppu().set_vram(&self.vram.buffer); gb.rom().set_ram_data(&self.mbc_ram.buffer); gb.mmu().write_many(0xfe00, &self.oam.buffer); gb.mmu().write_many(0xff80, &self.hram.buffer);