Complete initial tests for startup
Some checks failed
Cargo Build & Test / Rust project - latest (stable) (push) Failing after 8s
Some checks failed
Cargo Build & Test / Rust project - latest (stable) (push) Failing after 8s
This commit is contained in:
119
src/ppu.rs
119
src/ppu.rs
@@ -1,6 +1,13 @@
|
||||
use iced::{advanced::graphics::geometry::Renderer, widget::canvas::{Fill, Frame}, Point, Size};
|
||||
use iced::{
|
||||
Point, Size,
|
||||
advanced::graphics::geometry::Renderer,
|
||||
widget::canvas::{Fill, Frame},
|
||||
};
|
||||
|
||||
use crate::{hex_view::Memory, mem::{MemoryMap, Segment}};
|
||||
use crate::{
|
||||
hex_view::Memory,
|
||||
mem::{MemoryMap, Segment},
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Color {
|
||||
@@ -91,6 +98,15 @@ pub struct Mask {
|
||||
em_blue: bool,
|
||||
}
|
||||
|
||||
const COLORS: &'static [Color; 0b11_1111] = &[
|
||||
Color { r: 0, g: 0, b: 0}; 0b11_1111
|
||||
];
|
||||
|
||||
pub struct Palette {
|
||||
colors: &'static [Color; 0b11_1111],
|
||||
ram: [u8; 0x20]
|
||||
}
|
||||
|
||||
pub struct PPU {
|
||||
// registers: PPURegisters,
|
||||
frame_count: usize,
|
||||
@@ -104,6 +120,7 @@ pub struct PPU {
|
||||
pub vblank: bool,
|
||||
|
||||
pub(crate) memory: MemoryMap<PPUMMRegisters>,
|
||||
palette: Palette,
|
||||
background: Background,
|
||||
oam: OAM,
|
||||
pub render_buffer: RenderBuffer<256, 240>,
|
||||
@@ -145,11 +162,12 @@ impl PPU {
|
||||
em_green: false,
|
||||
em_blue: false,
|
||||
},
|
||||
palette: Palette { colors: COLORS, ram: [0; _] },
|
||||
vblank: false,
|
||||
frame_count: 0,
|
||||
nmi_enabled: false,
|
||||
nmi_waiting: false,
|
||||
even: true, // ??
|
||||
even: false,
|
||||
scanline: 0,
|
||||
pixel: 25,
|
||||
render_buffer: RenderBuffer::empty(),
|
||||
@@ -157,7 +175,8 @@ impl PPU {
|
||||
Segment::rom("CHR ROM", 0x0000, rom),
|
||||
Segment::ram("Internal VRAM", 0x2000, 0x1000),
|
||||
Segment::mirror("Mirror of VRAM", 0x3000, 0x0F00, 1),
|
||||
Segment::reg("Palette Control", 0x3F00, 0x0100, PPUMMRegisters::Palette),
|
||||
Segment::reg("Palette Control", 0x3F00, 0x0020, PPUMMRegisters::Palette),
|
||||
Segment::mirror("Mirror of Palette", 0x3F20, 0x00E0, 3),
|
||||
]),
|
||||
background: Background {
|
||||
v: 0,
|
||||
@@ -182,6 +201,10 @@ impl PPU {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn rendering_enabled(&self) -> bool {
|
||||
self.mask.enable_background || self.mask.enable_sprites
|
||||
}
|
||||
|
||||
pub fn read_reg(&mut self, offset: u16) -> u8 {
|
||||
match offset {
|
||||
0 => panic!("ppuctrl is write-only"),
|
||||
@@ -190,7 +213,6 @@ impl PPU {
|
||||
let tmp = if self.vblank { 0b1000_0000 } else { 0 };
|
||||
self.vblank = false;
|
||||
self.background.w = false;
|
||||
println!("Reading status: {:02X}", tmp);
|
||||
tmp
|
||||
}
|
||||
3 => panic!("oamaddr is write-only"),
|
||||
@@ -227,7 +249,7 @@ impl PPU {
|
||||
self.mask.background_on_left_edge = val & 0b0000_0010 != 0;
|
||||
self.mask.sprites_on_left_edge = val & 0b0000_0100 != 0;
|
||||
self.mask.enable_background = val & 0b0000_1000 != 0;
|
||||
self.mask.enable_background = val & 0b0001_0000 != 0;
|
||||
self.mask.enable_sprites = val & 0b0001_0000 != 0;
|
||||
self.mask.em_red = val & 0b0010_0000 != 0;
|
||||
self.mask.em_green = val & 0b0100_0000 != 0;
|
||||
self.mask.em_blue = val & 0b1000_0000 != 0;
|
||||
@@ -284,7 +306,9 @@ impl PPU {
|
||||
pub fn run_one_clock_cycle(&mut self) -> bool {
|
||||
self.cycle += 1;
|
||||
self.pixel += 1;
|
||||
if self.scanline == 261 && (self.pixel == 341 || (self.pixel == 340 && self.even)) {
|
||||
if self.scanline == 261
|
||||
&& (self.pixel == 341 || (self.pixel == 340 && self.even && self.rendering_enabled()))
|
||||
{
|
||||
self.scanline = 0;
|
||||
self.pixel = 0;
|
||||
self.even = !self.even;
|
||||
@@ -388,10 +412,22 @@ impl PPU {
|
||||
Size::new(1., 1.),
|
||||
match (low & (1 << bit) != 0, high & (1 << bit) != 0) {
|
||||
(false, false) => Color { r: 0, g: 0, b: 0 },
|
||||
(true, false) => Color { r: 64, g: 64, b: 64 },
|
||||
(false, true) => Color { r: 128, g: 128, b: 128 },
|
||||
(true, true) => Color { r: 255, g: 255, b: 255 },
|
||||
}
|
||||
(true, false) => Color {
|
||||
r: 64,
|
||||
g: 64,
|
||||
b: 64,
|
||||
},
|
||||
(false, true) => Color {
|
||||
r: 128,
|
||||
g: 128,
|
||||
b: 128,
|
||||
},
|
||||
(true, true) => Color {
|
||||
r: 255,
|
||||
g: 255,
|
||||
b: 255,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -409,14 +445,29 @@ impl PPU {
|
||||
let high = self.memory.peek(name + y_off + 8).unwrap();
|
||||
for bit in 0..8 {
|
||||
frame.fill_rectangle(
|
||||
Point::new(x as f32 * 8. + 8. - bit as f32, y as f32 * 8. + y_off as f32),
|
||||
Point::new(
|
||||
x as f32 * 8. + 8. - bit as f32,
|
||||
y as f32 * 8. + y_off as f32,
|
||||
),
|
||||
Size::new(1., 1.),
|
||||
match (low & (1 << bit) != 0, high & (1 << bit) != 0) {
|
||||
(false, false) => Color { r: 0, g: 0, b: 0 },
|
||||
(true, false) => Color { r: 64, g: 64, b: 64 },
|
||||
(false, true) => Color { r: 128, g: 128, b: 128 },
|
||||
(true, true) => Color { r: 255, g: 255, b: 255 },
|
||||
}
|
||||
(true, false) => Color {
|
||||
r: 64,
|
||||
g: 64,
|
||||
b: 64,
|
||||
},
|
||||
(false, true) => Color {
|
||||
r: 128,
|
||||
g: 128,
|
||||
b: 128,
|
||||
},
|
||||
(true, true) => Color {
|
||||
r: 255,
|
||||
g: 255,
|
||||
b: 255,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -431,14 +482,29 @@ impl PPU {
|
||||
let high = self.memory.peek(name + y_off + 8 + 0x1000).unwrap();
|
||||
for bit in 0..8 {
|
||||
frame.fill_rectangle(
|
||||
Point::new(x as f32 * 8. + 8. - bit as f32, y as f32 * 8. + y_off as f32 + 130.),
|
||||
Point::new(
|
||||
x as f32 * 8. + 8. - bit as f32,
|
||||
y as f32 * 8. + y_off as f32 + 130.,
|
||||
),
|
||||
Size::new(1., 1.),
|
||||
match (low & (1 << bit) != 0, high & (1 << bit) != 0) {
|
||||
(false, false) => Color { r: 0, g: 0, b: 0 },
|
||||
(true, false) => Color { r: 64, g: 64, b: 64 },
|
||||
(false, true) => Color { r: 128, g: 128, b: 128 },
|
||||
(true, true) => Color { r: 255, g: 255, b: 255 },
|
||||
}
|
||||
(true, false) => Color {
|
||||
r: 64,
|
||||
g: 64,
|
||||
b: 64,
|
||||
},
|
||||
(false, true) => Color {
|
||||
r: 128,
|
||||
g: 128,
|
||||
b: 128,
|
||||
},
|
||||
(true, true) => Color {
|
||||
r: 255,
|
||||
g: 255,
|
||||
b: 255,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -447,6 +513,17 @@ impl PPU {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn render_palette<R: Renderer>(&self, frame: &mut Frame<R>) {
|
||||
frame.fill_rectangle(
|
||||
Point::new(0., 0.),
|
||||
Size::new(10., 10.),
|
||||
Color {
|
||||
r: todo!(),
|
||||
g: todo!(),
|
||||
b: todo!(),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user