WIP PPU registers and background rendering

This commit is contained in:
2022-12-14 00:13:42 -05:00
parent a3f12e61b4
commit ac4c749e37
6 changed files with 280 additions and 3 deletions
+2 -2
View File
@@ -4,8 +4,8 @@ use crate::rom::ROM;
use crate::rom::lo_rom::LoROM;
pub struct Emulator {
cpu: CPU,
bus: Bus,
pub cpu: CPU,
pub bus: Bus,
pub rom: Box<dyn ROM>,
}
+109
View File
@@ -60,6 +60,56 @@ pub const WOBJLOG: u16 = 0x212B; // Window 2 Mask Logic (W)
pub const TMW: u16 = 0x212E; // Window Area Main Screen Disable (W)
pub const TSW: u16 = 0x212F; // Window Area Sub Screen Disable (W)
pub const MAX_BG_WIDTH: usize = 16 * 64;
pub const MAX_BG_HEIGHT: usize = 16 * 64;
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum TileSize {
P8x8,
P16x16,
P16x8,
}
impl TileSize {
pub fn to_usize(&self) -> (usize, usize) {
match self {
Self::P8x8 => (8, 8),
Self::P16x16 => (16, 16),
Self::P16x8 => (16, 8),
}
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum BgSize {
T32x32,
T64x32, // V Mirror
T32x64, // H Mirror
T64x64, // H Mirror
}
impl BgSize {
pub fn to_usize(&self) -> (usize, usize) {
match self {
Self::T32x32 => (32, 32),
Self::T64x32 => (64, 32),
Self::T32x64 => (32, 64),
Self::T64x64 => (64, 64),
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum Background {
Bg1,
Bg2,
Bg3,
Bg4,
}
pub struct PPURegisters {
data: [u8; 256],
}
@@ -78,4 +128,63 @@ impl PPURegisters {
pub fn write(&mut self, address: u16, value: u8) {
self.data[(address as usize) - 0x2100] = value;
}
/// 7 BG4 Tile Size (0=8x8, 1=16x16) ;\(BgMode0..4: variable 8x8 or 16x16)
/// 6 BG3 Tile Size (0=8x8, 1=16x16) ; (BgMode5: 8x8 acts as 16x8)
/// 5 BG2 Tile Size (0=8x8, 1=16x16) ; (BgMode6: fixed 16x8?)
/// 4 BG1 Tile Size (0=8x8, 1=16x16) ;/(BgMode7: fixed 8x8)
/// 3 BG3 Priority in Mode 1 (0=Normal, 1=High)
/// 2-0 BG Screen Mode (0..7 = see below)
pub fn get_bg_tile_size(&self, background: Background) -> TileSize {
let byte = self.read(BGMODE);
let bit = match background {
Background::Bg1 => byte >> 3 & 0b1 == 1, // Bit 4
Background::Bg2 => byte >> 4 & 0b1 == 1, // Bit 5
Background::Bg3 => byte >> 5 & 0b1 == 1, // Bit 6
Background::Bg4 => byte >> 6 & 0b1 == 1, // Bit 7
};
match bit {
true => TileSize::P16x16,
false => TileSize::P8x8,
}
}
pub fn get_bg_size(&self, background: Background) -> BgSize {
let byte = match background {
Background::Bg1 => self.read(BG1SC),
Background::Bg2 => self.read(BG2SC),
Background::Bg3 => self.read(BG3SC),
Background::Bg4 => self.read(BG4SC),
};
match byte & 0b11 {
0 => BgSize::T32x32,
1 => BgSize::T64x32,
2 => BgSize::T32x64,
3 => BgSize::T64x64,
_ => unreachable!(),
}
}
}
#[cfg(test)]
mod ppu_registers_test {
use super::*;
#[test]
fn test_get_bg_tile_size() {
let mut registers = PPURegisters::new();
registers.write(BGMODE, 0b00000100);
assert_eq!(registers.get_bg_tile_size(Background::Bg1), TileSize::P8x8);
registers.write(BGMODE, 0b00001100);
assert_eq!(registers.get_bg_tile_size(Background::Bg1), TileSize::P16x16);
}
#[test]
fn test_get_bg_size() {
let mut registers = PPURegisters::new();
registers.write(BG1SC, 2);
assert_eq!(registers.get_bg_size(Background::Bg1), BgSize::T32x64);
}
}