aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs5
-rw-r--r--src/memory.rs14
-rw-r--r--src/ppu.rs48
3 files changed, 28 insertions, 39 deletions
diff --git a/src/main.rs b/src/main.rs
index 9220694..57af3e4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -89,6 +89,7 @@ impl SDLWindow {
}
}
+ #[inline(always)]
fn poll(&self) -> bool {
for event in self.events.borrow_mut().poll_iter() {
match event {
@@ -239,9 +240,9 @@ fn main() {
if duration_per_frame > e {
let diff = duration_per_frame - e;
sleep(diff);
- println!("{} faster", diff.subsec_nanos() as f64 / 1e6);
+ //println!("{} faster", diff.subsec_nanos() as f64 / 1e6);
} else {
- println!("{} slower", (e - duration_per_frame).subsec_nanos() as f64 / 1e6);
+ //println!("{} slower", (e - duration_per_frame).subsec_nanos() as f64 / 1e6);
}
timer = Instant::now();
cnt -= CYC_PER_FRAME;
diff --git a/src/memory.rs b/src/memory.rs
index 6d83cbc..d2c9e52 100644
--- a/src/memory.rs
+++ b/src/memory.rs
@@ -1,5 +1,5 @@
#![allow(dead_code)]
-use ppu::{PPU, PMem};
+use ppu::PPU;
use mos6502::CPU;
use cartridge::{MirrorType, Cartridge};
use core::cell::{UnsafeCell, Cell};
@@ -133,31 +133,31 @@ fn get_mirror_palette(addr: u16) -> u16 {
} else { addr }
}
-impl<'a> PMem for PPUMemory<'a> {
+impl<'a> PPUMemory<'a> {
#[inline(always)]
- fn read_nametable(&self, addr: u16) -> u8 {
+ pub fn read_nametable(&self, addr: u16) -> u8 {
let kind = self.cart.mirror_type;
unsafe {(*self.nametable.get())[(get_mirror_addr(kind, addr) & 0x7ff) as usize]}
}
#[inline(always)]
- fn read_palette(&self, addr: u16) -> u8 { unsafe {
+ pub fn read_palette(&self, addr: u16) -> u8 { unsafe {
(*self.palette.get())[get_mirror_palette(addr) as usize]
}}
#[inline(always)]
- fn write_nametable(&self, addr: u16, data: u8) {
+ pub fn write_nametable(&self, addr: u16, data: u8) {
let kind = self.cart.mirror_type;
unsafe {(*self.nametable.get())[(get_mirror_addr(kind, addr) & 0x7ff) as usize] = data}
}
#[inline(always)]
- fn write_palette(&self, addr: u16, data: u8) { unsafe {
+ pub fn write_palette(&self, addr: u16, data: u8) { unsafe {
(*self.palette.get())[get_mirror_palette(addr) as usize] = data;
}}
#[inline(always)]
- fn read_mapper(&self, addr: u16) -> u8 {
+ pub fn read_mapper(&self, addr: u16) -> u8 {
self.mapper.read(addr)
}
diff --git a/src/ppu.rs b/src/ppu.rs
index b317b9b..89c4530 100644
--- a/src/ppu.rs
+++ b/src/ppu.rs
@@ -1,5 +1,5 @@
#![allow(dead_code)]
-use memory::VMem;
+use memory::{VMem, PPUMemory};
use mos6502::CPU;
use core::intrinsics::transmute;
@@ -9,15 +9,6 @@ pub trait Screen {
fn render(&self);
}
-pub trait PMem: VMem {
- fn read_nametable(&self, addr: u16) -> u8;
- fn read_palette(&self, addr: u16) -> u8;
- fn write_nametable(&self, addr: u16, data: u8);
- fn write_palette(&self, addr: u16, data: u8);
- fn read_mapper(&self, addr: u16) -> u8;
- fn write_mapper(&self, addr: u16, data: u8);
-}
-
#[repr(C, packed)]
#[derive(Copy, Clone)]
struct Sprite {
@@ -60,7 +51,7 @@ pub struct PPU<'a> {
buffered_read: u8,
early_read: bool,
/* IO */
- mem: &'a PMem,
+ mem: &'a PPUMemory<'a>,
scr: &'a Screen,
}
@@ -313,12 +304,12 @@ impl<'a> PPU<'a> {
#[inline(always)]
fn clear_sprite(&mut self) {
- if self.scanline == 261 { return }
+ assert!(self.scanline != 261);
self.oam2 = [0x100; 8];
}
fn eval_sprite(&mut self) {
- if self.scanline == 261 { return }
+ assert!(self.scanline != 261);
/* we use scanline here because s.y is the (actual y) - 1 */
let mut nidx = 0;
let mut n = 0;
@@ -450,7 +441,7 @@ impl<'a> PPU<'a> {
}));
}
- pub fn new(mem: &'a PMem, scr: &'a Screen) -> Self {
+ pub fn new(mem: &'a PPUMemory<'a>, scr: &'a Screen) -> Self {
let ppuctl = 0x00;
let ppumask = 0x00;
let ppustatus = 0xa0;
@@ -499,20 +490,16 @@ impl<'a> PPU<'a> {
return false;
}
let visible_line = self.scanline < 240;
- let pre_render = self.scanline == 261;
- self.rendering = pre_render || visible_line;
- if pre_render && cycle == 1 {
- /* clear vblank, sprite zero hit & overflow */
- self.ppustatus &= !(PPU::FLAG_VBLANK |
- PPU::FLAG_SPRITE_ZERO | PPU::FLAG_OVERFLOW);
-
- } else if self.rendering && (self.get_show_bg() || self.get_show_sp()) {
- if pre_render && 279 < cycle && cycle < 305 {
+ let pre_line = self.scanline == 261;
+ self.rendering = pre_line || visible_line;
+ if self.rendering && (self.get_show_bg() || self.get_show_sp()) {
+ if pre_line && 279 < cycle && cycle < 305 {
self.reset_y();
} else {
let visible_cycle = 0 < cycle && cycle < 257; /* 1..256 */
- let fetch_cycle = visible_cycle || (320 < cycle && cycle < 337);
- if fetch_cycle { /* 1..256 and 321..336 */
+ let prefetch_cycle = 320 < cycle && cycle < 337;
+ let fetch_cycle = visible_cycle || prefetch_cycle;
+ if (visible_line && fetch_cycle) || (pre_line && prefetch_cycle) {
match cycle & 0x7 {
1 => {
self.load_bgtile();
@@ -530,15 +517,11 @@ impl<'a> PPU<'a> {
256 => self.wrapping_inc_y(),
_ => ()
}
- if visible_line && visible_cycle {
+ if visible_cycle {
self.render_pixel();
self.shift_sprites();
}
self.shift_bgtile();
- } else if cycle > 336 { /* 337..340 */
- if cycle & 1 == 1 {
- self.fetch_nametable_byte();
- }
} else if cycle == 257 {
/* we don't emulate fetch to per cycle precision because all data are fetched
* from the secondary OAM which is not subject to any change during this
@@ -546,6 +529,11 @@ impl<'a> PPU<'a> {
self.reset_cx();
self.fetch_sprite();
}
+ if pre_line && cycle == 1 {
+ /* clear vblank, sprite zero hit & overflow */
+ self.ppustatus &= !(PPU::FLAG_VBLANK |
+ PPU::FLAG_SPRITE_ZERO | PPU::FLAG_OVERFLOW);
+ }
}
} else if self.scanline == 241 && cycle == 1 {
if !self.early_read {