Add a new PPU testsuite based on a transistor level simulation of RP2C02.

This commit is contained in:
Jan Bujak 2016-10-30 00:16:54 +02:00
parent a9ef8d50e4
commit 4016b60e49
29 changed files with 18421 additions and 0 deletions

2
.gitignore vendored
View file

@ -10,3 +10,5 @@ nes/target
nes/Cargo.lock
emumisc/target
emumisc/Cargo.lock
rp2c02-testsuite/target
rp2c02-testsuite/Cargo.lock

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "rp2c02-testsuite/generator/phantom2c02"]
path = rp2c02-testsuite/generator/phantom2c02
url = https://github.com/koute/phantom2c02.git

View file

@ -17,6 +17,9 @@ path = "../mos6502"
[dev-dependencies.nes-testsuite]
path = "../nes-testsuite"
[dev-dependencies.rp2c02-testsuite]
path = "../rp2c02-testsuite"
[profile.test]
opt-level = 2
debug = true

View file

@ -20,6 +20,10 @@ extern crate bitflags;
#[macro_use]
extern crate nes_testsuite;
#[cfg(test)]
#[macro_use]
extern crate rp2c02_testsuite;
mod memory_map;
mod rp2c02_scheduler;
mod rp2c02;

View file

@ -1610,3 +1610,149 @@ mod tests {
assert_eq!( ppu.peek( 0x3F00 + 31 ), 31 );
}
}
#[cfg(test)]
mod test_ppu {
use super::{Context, State, Private};
use rp2c02_testsuite::TestPPU;
use std::cell::Cell;
use std::fmt;
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct MemoryOperation {
pub address: u16,
pub value: u8
}
impl fmt::Debug for MemoryOperation {
fn fmt( &self, fmt: &mut fmt::Formatter ) -> fmt::Result {
write!( fmt, "{{ address: 0x{:04X}, value: 0x{:02X} }}", self.address, self.value )
}
}
struct Instance {
state: State,
memory: [u8; 0x2400],
last_vram_read: Cell< Option< MemoryOperation > >,
expected_vram_read: Option< Option< MemoryOperation > >
}
impl Context for Instance {
fn state_mut( &mut self ) -> &mut State {
&mut self.state
}
fn state( &self ) -> &State {
&self.state
}
fn on_frame_was_generated( &mut self ) {}
fn set_vblank_nmi( &mut self, _: bool ) {}
fn peek_video_memory( &self, address: u16 ) -> u8 {
// The simulator uses one screen mirroring of the background tilemaps.
let value = self.memory[ ((address & 0x23FF) | (address & 0x2000)) as usize ];
self.last_vram_read.set( Some( MemoryOperation {
address: address,
value: value
}));
value
}
fn poke_video_memory( &mut self, _: u16, _: u8 ) {
unreachable!();
}
}
impl Instance {
fn new() -> Self {
Instance {
state: State::new(),
memory: [0; 0x2400],
last_vram_read: Cell::new( None ),
expected_vram_read: None
}
}
}
impl TestPPU for Instance {
fn expect_vram_read( &mut self, address: u16, value: u8 ) {
self.expected_vram_read = Some( Some( MemoryOperation {
address: address,
value: value
}));
}
fn expect_no_vram_read( &mut self ) {
self.expected_vram_read = Some( None );
}
fn get_current_address( &self ) -> u16 {
self.state.current_address
}
fn read_ioreg( &mut self, index: u8 ) -> u8 {
match index {
2 => self.peek_ppustatus(),
4 => self.peek_oamdata(),
7 => self.peek_ppudata(),
_ => unreachable!()
}
}
fn read_secondary_sprite_ram( &self, index: u8 ) -> u8 {
self.state.secondary_sprite_list_ram[ index as usize ]
}
fn write_ioreg( &mut self, index: u8, value: u8 ) {
match index {
0 => self.poke_ppuctrl( value ),
1 => self.poke_ppumask( value ),
3 => self.poke_oamaddr( value ),
4 => self.poke_oamdata( value ),
5 => self.poke_ppuscroll( value ),
6 => self.poke_ppuaddr( value ),
7 => self.poke_ppudata( value ),
_ => unreachable!()
}
}
fn write_vram( &mut self, address: u16, value: u8 ) {
self.memory[ address as usize ] = value;
}
fn write_palette_ram( &mut self, index: u8, value: u8 ) {
self.state.palette_ram[ index as usize ] = value;
}
fn write_sprite_ram( &mut self, index: u8, value: u8 ) {
self.state.sprite_list_ram[ index as usize ] = value;
}
fn write_secondary_sprite_ram( &mut self, index: u8, value: u8 ) {
self.state.secondary_sprite_list_ram[ index as usize] = value;
}
fn step_pixel( &mut self ) {
self.last_vram_read = Cell::new( None );
self.execute();
if let Some( expected_vram_read ) = self.expected_vram_read.take() {
assert_eq!( self.last_vram_read.get(), expected_vram_read );
}
}
fn scanline( &self ) -> u16 {
self.state.n_scanline
}
fn dot( &self ) -> u16 {
self.state.n_dot
}
}
rp2c02_testsuite!( Instance );
}

View file

@ -0,0 +1,7 @@
[package]
name = "rp2c02-testsuite"
version = "0.1.0"
authors = ["Jan Bujak <j@exia.io>"]
build = "build.rs"
[dependencies]

79
rp2c02-testsuite/build.rs Normal file
View file

@ -0,0 +1,79 @@
use std::env;
use std::path::{Path, PathBuf};
use std::fs::{self, File};
use std::io::{self, Read, Write};
fn list_files< P: AsRef< Path > >( path: P ) -> io::Result< Vec< PathBuf > > {
let mut output = Vec::new();
for entry_opt in try!( fs::read_dir( path.as_ref() ) ) {
let entry = try!( entry_opt );
let metadata = try!( fs::metadata( entry.path() ) );
if metadata.is_dir() {
continue;
} else {
output.push( entry.path() )
}
}
Ok( output )
}
fn main() {
let files = list_files( "src/tests" ).unwrap();
let modules: Vec< _ > = files.into_iter().flat_map( |path| {
let filename = path.file_name().unwrap().to_string_lossy();
if filename.starts_with( "test_" ) == false {
None
} else {
Some( filename[ 0..filename.len() - 3 ].to_owned() )
}
}).collect();
let out_dir: PathBuf = env::var_os( "CARGO_MANIFEST_DIR" ).unwrap().into();
let out_filename = out_dir.join( "src" ).join( "tests" ).join( "mod.rs" );
let mut out = Vec::new();
writeln!( out, "// This file was AUTOGENERATED; do not edit!" ).unwrap();
writeln!( out, "" ).unwrap();
for module_name in &modules {
writeln!( out, "mod {};", module_name ).unwrap();
}
writeln!( out, "" ).unwrap();
for module_name in &modules {
writeln!( out, "pub use tests::{}::*;", module_name ).unwrap();
}
writeln!( out, "" ).unwrap();
writeln!( out, "#[macro_export]" ).unwrap();
writeln!( out, "macro_rules! rp2c02_testsuite {{" ).unwrap();
writeln!( out, " ($interface:ident) => (" ).unwrap();
writeln!( out, " mod rp2c02_testsuite {{" ).unwrap();
for module_name in &modules {
writeln!( out, " #[test]" ).unwrap();
writeln!( out, " fn {}() {{", module_name ).unwrap();
writeln!( out, " use super::$interface;" ).unwrap();
writeln!( out, " let mut ppu = $interface::new();" ).unwrap();
writeln!( out, " $crate::tests::{}( &mut ppu );", module_name ).unwrap();
writeln!( out, " }}" ).unwrap();
}
writeln!( out, " }}" ).unwrap();
writeln!( out, " )" ).unwrap();
writeln!( out, "}}" ).unwrap();
if let Ok( mut fp ) = File::open( &out_filename ) {
let mut old_contents = Vec::new();
if let Ok( _ ) = fp.read_to_end( &mut old_contents ) {
if old_contents == out {
return; // Nothing changed; no point in writing to disk.
}
}
}
let mut fp = File::create( out_filename ).unwrap();
fp.write_all( &out[..] ).unwrap();
}

View file

@ -0,0 +1,203 @@
"use strict";
var fs = require( "fs" );
var phantom2c02 = require( "./phantom2c02/phantom2c02" );
var _ = require( "./phantom2c02/lib/lodash" );
var sprintf = require( "./phantom2c02/lib/sprintf" ).sprintf;
function generate( name, callback ) {
phantom2c02.create( function( ctx ) {
var output = "";
var automatically_output_code = true;
var disable_automatic_code_output = function( callback ) {
var previous = automatically_output_code;
automatically_output_code = false;
var result = callback();
automatically_output_code = previous;
return result;
};
var indent = function( callback ) {
self.indentation += 4;
callback();
self.indentation -= 4;
};
var output_loop = function( times, callback, extra_args ) {
extra_args = extra_args || {};
self.println( "for %s in 0..%iu32 {", extra_args.variable || "i", times );
indent( callback );
if( extra_args.output_position === true ) {
self.println( "} // %s -> %s", ctx.get_position().add( -1 ), ctx.get_position() );
} else {
self.println( "}" );
}
};
var self = {
indentation: 0,
println: function() {
var args = Array.prototype.slice.call( arguments );
var line = sprintf.apply( null, args );
self.repeat( self.indentation, function() {
output += " ";
});
output += line;
output += "\n";
},
step_pixel: ctx.step_pixel,
step_scanline: ctx.step_scanline,
cpu_write_and_step: ctx.cpu_write_and_step,
write_oam: ctx.write_oam,
write_sprite_to_oam: ctx.write_sprite_to_oam,
write_secondary_oam: ctx.write_secondary_oam,
write_sprite_to_secondary_oam: ctx.write_sprite_to_secondary_oam,
write_palette_ram: ctx.write_palette_ram,
write_vram: ctx.write_vram,
test: {
next_vram_read: function() {
if( ctx.is_reading_from_vram() ) {
self.println( "ppu.expect_vram_read( 0x%04X, 0x%02X );", ctx.get_address_bus(), ctx.get_data_bus() );
} else {
self.println( "ppu.expect_no_vram_read();" );
}
},
current_address: function() {
self.println( "assert_eq( ppu.get_current_address(), 0x%04X );", ctx.get_current_address() );
},
cpu_read: function( address ) {
var obj = ctx.resolve_io_port( address );
ctx.queue_cpu_read( obj, function( value ) {
self.println( "assert_eq( ppu.read_ioreg( %i ), 0x%02X );", (obj.address - 0x2000) & (8 - 1), value );
});
},
secondary_oam_contents: function() {
_.each( ctx.dump_secondary_oam(), function( value, index ) {
self.println( "assert_eq( ppu.read_secondary_sprite_ram( %i ), 0x%02X );", index, value );
});
}
},
fill_vram_with_test_data: function() {
disable_automatic_code_output( function() {
// Fill out the first pattern table.
self.repeat( 0x1000, function( addr ) {
self.write_vram( addr, (addr + 0x80) & 0xFF );
});
// Fill out the first nametable.
self.repeat( 960, function( offset ) {
self.write_vram( 0x2000 + offset, (offset + 0x80) & 0xFF );
});
// Fill out the first attribute table.
self.repeat( 64, function( offset ) {
self.write_vram( 0x2000 + 960 + offset, 0x80 | offset );
});
});
output_loop( 0x1000, function() {
self.println( "ppu.write_vram( i as u16, (i + 0x80) as u8 );" );
});
output_loop( 960, function() {
self.println( "ppu.write_vram( (0x2000 + i) as u16, (i + 0x80) as u8 );" );
});
output_loop( 64, function() {
self.println( "ppu.write_vram( (0x2000 + 960 + i) as u16, (0x80 | i) as u8 );" );
});
},
repeat: function( times, callback ) {
if( callback === ctx.step_pixel ) {
disable_automatic_code_output( function() {
ctx.repeat( times, callback );
output_loop( times, _.partial( self.println, "ppu.step_pixel();" ), { output_position: true, variable: "_" } );
});
} else if( callback === ctx.step_scanline ) {
disable_automatic_code_output( function() {
ctx.repeat( times, callback );
output_loop( times, _.partial( self.println, "ppu.step_scanline();" ), { output_position: true, variable: "_" } );
});
} else {
ctx.repeat( times, callback );
}
},
simulator: ctx
};
ctx.on_write_vram_called = function( address, value ) {
if( !automatically_output_code ) return;
self.println( "ppu.write_vram( 0x%04X, 0x%02X );", address, value );
};
ctx.on_write_palette_ram_called = function( offset, value ) {
if( !automatically_output_code ) return;
self.println( "ppu.write_palette_ram( %i, 0x%02X );", offset, value );
};
ctx.on_write_oam_called = function( offset, value ) {
if( !automatically_output_code ) return;
self.println( "ppu.write_sprite_ram( %i, 0x%02X );", offset, value );
};
ctx.on_write_secondary_oam_called = function( offset, value ) {
if( !automatically_output_code ) return;
self.println( "ppu.write_secondary_sprite_ram( %i, 0x%02X );", offset, value );
};
ctx.on_cpu_write_called = function( address, value ) {
if( !automatically_output_code ) return;
self.println( "ppu.write_ioreg( %i, 0x%02X );", (address - 0x2000) & (8 - 1), value );
};
ctx.on_step_pixel_called = function() {
if( !automatically_output_code ) return;
self.println( "ppu.step_pixel(); // %s -> %s", ctx.get_position().add( -1 ), ctx.get_position() );
};
ctx.on_step_scanline_called = function() {
if( !automatically_output_code ) return;
self.println( "ppu.step_scanline();" );
};
console.log( "Generating '" + name + "'..." );
self.println( "// This file was AUTOGENERATED; do not edit!" );
self.println( "" );
self.println( "#[allow(unused_imports)]" );
self.println( "use super::super::assert_eq;" );
self.println( "use TestPPU;" );
self.println( "" );
self.println( "#[inline(never)]" );
self.println( "pub fn test_" + name + "( ppu: &mut TestPPU ) {" );
self.indentation += 4;
self.println( "assert_eq!( ppu.scanline(), %s );", ctx.get_scanline() );
self.println( "assert_eq!( ppu.dot(), %s );", ctx.get_dot() );
callback( self );
self.println( "assert_eq!( ppu.scanline(), %s );", ctx.get_scanline() );
self.println( "assert_eq!( ppu.dot(), %s );", ctx.get_dot() );
self.indentation -= 4;
self.println( "}" );
fs.write( module.dirname + "/../src/tests/test_" + name + ".rs", output );
ctx.exit();
});
}
module.exports.generate = generate;
module.exports.ppumask = phantom2c02.ppumask;
module.exports.ppuctrl = phantom2c02.ppuctrl;
module.exports.sprite = phantom2c02.sprite;

View file

@ -0,0 +1,25 @@
"use strict";
var common = require( "./common" );
var ppumask = common.ppumask;
var sprite = common.sprite;
common.generate( "current_address_during_background_rendering", function( ctx ) {
var ppumask_value = ppumask()
.set_show_background( true )
.set_show_background_in_leftmost_8_pixels( true );
ctx.fill_vram_with_test_data();
ctx.cpu_write_and_step( ppumask_value );
ctx.step_scanline();
var test = function() {
ctx.test.current_address();
ctx.step_pixel();
};
ctx.repeat( 2 * 341, test );
ctx.repeat( 5, ctx.step_scanline );
ctx.repeat( 2 * 341, test );
});

View file

@ -0,0 +1,35 @@
"use strict";
var _ = require( "./phantom2c02/lib/lodash" );
var common = require( "./common" );
var ppumask = common.ppumask;
var sprite = common.sprite;
common.generate( "current_address_during_sprite_rendering", function( ctx ) {
var ppumask_value = ppumask()
.set_show_sprites( true )
.set_show_sprites_in_leftmost_8_pixels( true );
ctx.fill_vram_with_test_data();
ctx.cpu_write_and_step( ppumask_value );
ctx.step_scanline();
var test = function() {
ctx.repeat( 257, ctx.step_pixel ); // Skip sprite evaluation.
ctx.repeat( 32, _.partial( ctx.write_secondary_oam, _, 0xFF ) );
ctx.write_sprite_to_secondary_oam( 0, sprite({ x: 0, y: 0, tile: 0xAA }) );
ctx.write_sprite_to_secondary_oam( 1, sprite({ x: 8, y: 0, tile: 0xBA, flip_h: true }) );
ctx.write_sprite_to_secondary_oam( 2, sprite({ x: 16, y: 0, tile: 0xCA, flip_v: true }) );
ctx.write_sprite_to_secondary_oam( 3, sprite({ x: 24, y: 0, tile: 0xDA, flip_h: true, flip_v: true }) );
ctx.repeat( 64, function() {
ctx.test.current_address();
ctx.step_pixel();
});
ctx.step_scanline();
};
ctx.repeat( 3, test );
});

View file

@ -0,0 +1,30 @@
"use strict";
var _ = require( "./phantom2c02/lib/lodash" );
var common = require( "./common" );
var ppumask = common.ppumask;
var sprite = common.sprite;
common.generate( "current_address_during_sprite_rendering_without_sprites", function( ctx ) {
var ppumask_value = ppumask()
.set_show_sprites( true )
.set_show_sprites_in_leftmost_8_pixels( true );
ctx.fill_vram_with_test_data();
ctx.cpu_write_and_step( ppumask_value );
ctx.step_scanline();
var test = function() {
ctx.repeat( 257, ctx.step_pixel ); // Skip sprite evaluation.
ctx.test.secondary_oam_contents(); // This should contain [0x00, 0xFF, 0xFF, 0xFF, ...].
ctx.repeat( 64, function() {
ctx.test.current_address();
ctx.step_pixel();
});
ctx.step_scanline();
};
ctx.repeat( 24, test );
});

View file

@ -0,0 +1,20 @@
"use strict";
var _ = require( "./phantom2c02/lib/lodash" );
var common = require( "./common" );
var ppumask = common.ppumask;
var sprite = common.sprite;
common.generate( "current_address_when_not_rendering", function( ctx ) {
ctx.fill_vram_with_test_data();
ctx.step_scanline();
var test = function() {
ctx.test.current_address();
ctx.step_pixel();
};
ctx.repeat( 2 * 341, test );
ctx.repeat( 5, ctx.step_scanline );
ctx.repeat( 2 * 341, test );
});

View file

@ -0,0 +1,26 @@
"use strict";
var common = require( "./common" );
var ppumask = common.ppumask;
var sprite = common.sprite;
common.generate( "vram_access_during_background_rendering", function( ctx ) {
var ppumask_value = ppumask()
.set_show_background( true )
.set_show_background_in_leftmost_8_pixels( true );
ctx.fill_vram_with_test_data();
ctx.cpu_write_and_step( ppumask_value );
ctx.step_scanline();
ctx.repeat( 257, function() {
ctx.test.next_vram_read();
ctx.step_pixel();
});
ctx.repeat( 64, ctx.step_pixel );
ctx.repeat( 20, function() {
ctx.test.next_vram_read();
ctx.step_pixel();
});
});

View file

@ -0,0 +1,35 @@
"use strict";
var _ = require( "./phantom2c02/lib/lodash" );
var common = require( "./common" );
var ppumask = common.ppumask;
var sprite = common.sprite;
common.generate( "vram_access_during_sprite_rendering", function( ctx ) {
var ppumask_value = ppumask()
.set_show_sprites( true )
.set_show_sprites_in_leftmost_8_pixels( true );
ctx.fill_vram_with_test_data();
ctx.cpu_write_and_step( ppumask_value );
ctx.step_scanline();
var test = function() {
ctx.repeat( 257, ctx.step_pixel ); // Skip sprite evaluation.
ctx.repeat( 32, _.partial( ctx.write_secondary_oam, _, 0xFF ) );
ctx.write_sprite_to_secondary_oam( 0, sprite({ x: 0, y: 0, tile: 0xAA }) );
ctx.write_sprite_to_secondary_oam( 1, sprite({ x: 8, y: 0, tile: 0xBA, flip_h: true }) );
ctx.write_sprite_to_secondary_oam( 2, sprite({ x: 16, y: 0, tile: 0xCA, flip_v: true }) );
ctx.write_sprite_to_secondary_oam( 3, sprite({ x: 24, y: 0, tile: 0xDA, flip_h: true, flip_v: true }) );
ctx.repeat( 64, function() {
ctx.test.next_vram_read();
ctx.step_pixel();
});
ctx.step_scanline();
};
ctx.repeat( 3, test );
});

View file

@ -0,0 +1,40 @@
"use strict";
var _ = require( "./phantom2c02/lib/lodash" );
var common = require( "./common" );
var ppumask = common.ppumask;
var ppuctrl = common.ppuctrl;
var sprite = common.sprite;
common.generate( "vram_access_during_sprite_rendering_double_height", function( ctx ) {
var ppumask_value = ppumask()
.set_show_sprites( true )
.set_show_sprites_in_leftmost_8_pixels( true );
var ppuctrl_value = ppuctrl()
.set_double_height_sprite_mode( true );
ctx.fill_vram_with_test_data();
ctx.cpu_write_and_step( ppumask_value );
ctx.cpu_write_and_step( ppuctrl_value );
ctx.step_scanline();
var test = function() {
ctx.repeat( 257, ctx.step_pixel ); // Skip sprite evaluation.
ctx.repeat( 32, _.partial( ctx.write_secondary_oam, _, 0xFF ) );
ctx.write_sprite_to_secondary_oam( 0, sprite({ x: 0, y: 0, tile: 0xAA }) );
ctx.write_sprite_to_secondary_oam( 1, sprite({ x: 8, y: 0, tile: 0xBA, flip_h: true }) );
ctx.write_sprite_to_secondary_oam( 2, sprite({ x: 16, y: 0, tile: 0xCA, flip_v: true }) );
ctx.write_sprite_to_secondary_oam( 3, sprite({ x: 24, y: 0, tile: 0xDA, flip_h: true, flip_v: true }) );
ctx.repeat( 64, function() {
ctx.test.next_vram_read();
ctx.step_pixel();
});
ctx.step_scanline();
};
ctx.repeat( 11, test );
});

View file

@ -0,0 +1,76 @@
"use strict";
var _ = require( "./phantom2c02/lib/lodash" );
var common = require( "./common" );
var ppumask = common.ppumask;
var sprite = common.sprite;
common.generate( "vram_access_sprite_rendering_out_of_range", function( ctx ) {
var ppumask_value = ppumask()
.set_show_sprites( true )
.set_show_sprites_in_leftmost_8_pixels( true );
ctx.fill_vram_with_test_data();
ctx.cpu_write_and_step( ppumask_value );
ctx.step_scanline();
ctx.repeat( 7, ctx.step_scanline );
ctx.repeat( 2, function() {
ctx.repeat( 257, ctx.step_pixel ); // Skip sprite evaluation.
// Technically some of these will never appear on one of the tested scanlines,
// but it's a good idea to test it anyway to figure out how the PPU calculates
// the sprite pattern addresses.
ctx.write_sprite_to_secondary_oam( 0, sprite({ x: 0, y: 0, tile: 0x77 }) );
ctx.write_sprite_to_secondary_oam( 1, sprite({ x: 0, y: 1, tile: 0x88 }) );
ctx.write_sprite_to_secondary_oam( 2, sprite({ x: 0, y: 7, tile: 0x99 }) );
ctx.write_sprite_to_secondary_oam( 3, sprite({ x: 0, y: 8, tile: 0xAA }) );
ctx.write_sprite_to_secondary_oam( 4, sprite({ x: 0, y: 9, tile: 0xBB }) );
ctx.write_sprite_to_secondary_oam( 5, sprite({ x: 0, y: 15, tile: 0xCC }) );
ctx.write_sprite_to_secondary_oam( 6, sprite({ x: 0, y: 16, tile: 0xDD }) );
ctx.write_sprite_to_secondary_oam( 7, sprite({ x: 0, y: 255, tile: 0xEE }) );
/*
| SCANLINE | Y | OFFSET |
| 7 | 0 | 7 |
| 7 | 1 | 6 |
| 7 | 2 | 5 |
| 7 | 3 | 4 |
| 7 | 4 | 3 |
| 7 | 5 | 2 |
| 7 | 6 | 1 |
| 7 | 7 | 0 |
| 7 | 8 | 7 |
| 7 | 9 | 6 |
| 7 | 10 | 5 |
| 7 | 11 | 4 |
| 7 | 12 | 3 |
| 7 | 15 | 0 |
| 7 | 16 | 7 |
| 7 | 255 | 0 |
| 8 | 0 | 0 |
| 8 | 1 | 7 |
| 8 | 2 | 6 |
| 8 | 3 | 5 |
| 8 | 4 | 4 |
| 8 | 5 | 3 |
| 8 | 6 | 2 |
| 8 | 7 | 1 |
| 8 | 8 | 0 |
| 8 | 9 | 7 |
| 8 | 10 | 6 |
| 8 | 11 | 5 |
| 8 | 12 | 4 |
| 8 | 15 | 1 |
| 8 | 16 | 0 |
| 8 | 255 | 1 |
*/
ctx.repeat( 64, function() {
ctx.test.next_vram_read();
ctx.step_pixel();
});
ctx.step_scanline();
});
});

View file

@ -0,0 +1,38 @@
"use strict";
var _ = require( "./phantom2c02/lib/lodash" );
var common = require( "./common" );
var ppumask = common.ppumask;
var sprite = common.sprite;
common.generate( "vram_access_during_sprite_rendering_without_sprites", function( ctx ) {
var ppumask_value = ppumask()
.set_show_sprites( true )
.set_show_sprites_in_leftmost_8_pixels( true );
ctx.fill_vram_with_test_data();
ctx.cpu_write_and_step( ppumask_value );
ctx.step_scanline();
var test = function() {
ctx.repeat( 257, ctx.step_pixel ); // Skip sprite evaluation.
ctx.test.secondary_oam_contents(); // This should contain [0x00, 0xFF, 0xFF, 0xFF, ...].
// In this test the OAM is filled with zeros. The PPU fills the secondary OAM
// with 0xFF during dots 001..064; then during 065..256 it evaluates the OAM
// and searches for sprites to copy to the secondary OAM. One of the quirks
// of the PPU is that it *always* copies the first byte from a given sprite
// slot from OAM to the secondary OAM when evaluating it, so if OAM is filled
// with zeros and we haven't found any sprites to render on the next scanline
// the secondary OAM will be filled with [0x00, 0xFF, 0xFF, 0xFF, ...].
ctx.repeat( 64, function() {
ctx.test.next_vram_read();
ctx.step_pixel();
});
ctx.step_scanline();
};
ctx.repeat( 24, test );
});

@ -0,0 +1 @@
Subproject commit ce2a024b3aac348eb2306231828921085fc4f4a4

View file

@ -0,0 +1,40 @@
use std::fmt;
// TODO: Remove this once rustc will be able to compile
// functions with many assertions in a reasonable time.
//
// See: https://github.com/rust-lang/rust/issues/37468
fn assert_eq< T: PartialEq + fmt::Debug >( a: T, b: T ) {
assert_eq!( a, b );
}
pub trait TestPPU {
fn expect_vram_read( &mut self, address: u16, value: u8 );
fn expect_no_vram_read( &mut self );
fn get_current_address( &self ) -> u16;
fn read_ioreg( &mut self, index: u8 ) -> u8;
fn read_secondary_sprite_ram( &self, index: u8 ) -> u8;
fn write_ioreg( &mut self, index: u8, value: u8 );
fn write_palette_ram( &mut self, index: u8, value: u8 );
fn write_sprite_ram( &mut self, index: u8, value: u8 );
fn write_secondary_sprite_ram( &mut self, index: u8, value: u8 );
fn write_vram( &mut self, address: u16, value: u8 );
fn scanline( &self ) -> u16;
fn dot( &self ) -> u16;
fn step_pixel( &mut self );
fn step_scanline( &mut self ) {
let scanline = self.scanline();
while self.scanline() == scanline {
self.step_pixel();
}
}
}
#[macro_use]
#[doc(hidden)]
pub mod tests;

View file

@ -0,0 +1,83 @@
// This file was AUTOGENERATED; do not edit!
mod test_vram_access_during_sprite_rendering;
mod test_current_address_during_sprite_rendering_without_sprites;
mod test_vram_access_during_sprite_rendering_without_sprites;
mod test_current_address_when_not_rendering;
mod test_vram_access_during_sprite_rendering_double_height;
mod test_current_address_during_background_rendering;
mod test_vram_access_during_background_rendering;
mod test_current_address_during_sprite_rendering;
mod test_vram_access_sprite_rendering_out_of_range;
pub use tests::test_vram_access_during_sprite_rendering::*;
pub use tests::test_current_address_during_sprite_rendering_without_sprites::*;
pub use tests::test_vram_access_during_sprite_rendering_without_sprites::*;
pub use tests::test_current_address_when_not_rendering::*;
pub use tests::test_vram_access_during_sprite_rendering_double_height::*;
pub use tests::test_current_address_during_background_rendering::*;
pub use tests::test_vram_access_during_background_rendering::*;
pub use tests::test_current_address_during_sprite_rendering::*;
pub use tests::test_vram_access_sprite_rendering_out_of_range::*;
#[macro_export]
macro_rules! rp2c02_testsuite {
($interface:ident) => (
mod rp2c02_testsuite {
#[test]
fn test_vram_access_during_sprite_rendering() {
use super::$interface;
let mut ppu = $interface::new();
$crate::tests::test_vram_access_during_sprite_rendering( &mut ppu );
}
#[test]
fn test_current_address_during_sprite_rendering_without_sprites() {
use super::$interface;
let mut ppu = $interface::new();
$crate::tests::test_current_address_during_sprite_rendering_without_sprites( &mut ppu );
}
#[test]
fn test_vram_access_during_sprite_rendering_without_sprites() {
use super::$interface;
let mut ppu = $interface::new();
$crate::tests::test_vram_access_during_sprite_rendering_without_sprites( &mut ppu );
}
#[test]
fn test_current_address_when_not_rendering() {
use super::$interface;
let mut ppu = $interface::new();
$crate::tests::test_current_address_when_not_rendering( &mut ppu );
}
#[test]
fn test_vram_access_during_sprite_rendering_double_height() {
use super::$interface;
let mut ppu = $interface::new();
$crate::tests::test_vram_access_during_sprite_rendering_double_height( &mut ppu );
}
#[test]
fn test_current_address_during_background_rendering() {
use super::$interface;
let mut ppu = $interface::new();
$crate::tests::test_current_address_during_background_rendering( &mut ppu );
}
#[test]
fn test_vram_access_during_background_rendering() {
use super::$interface;
let mut ppu = $interface::new();
$crate::tests::test_vram_access_during_background_rendering( &mut ppu );
}
#[test]
fn test_current_address_during_sprite_rendering() {
use super::$interface;
let mut ppu = $interface::new();
$crate::tests::test_current_address_during_sprite_rendering( &mut ppu );
}
#[test]
fn test_vram_access_sprite_rendering_out_of_range() {
use super::$interface;
let mut ppu = $interface::new();
$crate::tests::test_vram_access_sprite_rendering_out_of_range( &mut ppu );
}
}
)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,567 @@
// This file was AUTOGENERATED; do not edit!
#[allow(unused_imports)]
use super::super::assert_eq;
use TestPPU;
#[inline(never)]
pub fn test_current_address_during_sprite_rendering( ppu: &mut TestPPU ) {
assert_eq!( ppu.scanline(), 261 );
assert_eq!( ppu.dot(), 0 );
for i in 0..4096u32 {
ppu.write_vram( i as u16, (i + 0x80) as u8 );
}
for i in 0..960u32 {
ppu.write_vram( (0x2000 + i) as u16, (i + 0x80) as u8 );
}
for i in 0..64u32 {
ppu.write_vram( (0x2000 + 960 + i) as u16, (0x80 | i) as u8 );
}
ppu.write_ioreg( 1, 0x14 );
ppu.step_pixel(); // 261 000 -> 261 001
ppu.step_pixel(); // 261 001 -> 261 002
ppu.step_pixel(); // 261 002 -> 261 003
ppu.step_scanline();
for _ in 0..257u32 {
ppu.step_pixel();
} // 000 256 -> 000 257
ppu.write_secondary_sprite_ram( 0, 0xFF );
ppu.write_secondary_sprite_ram( 1, 0xFF );
ppu.write_secondary_sprite_ram( 2, 0xFF );
ppu.write_secondary_sprite_ram( 3, 0xFF );
ppu.write_secondary_sprite_ram( 4, 0xFF );
ppu.write_secondary_sprite_ram( 5, 0xFF );
ppu.write_secondary_sprite_ram( 6, 0xFF );
ppu.write_secondary_sprite_ram( 7, 0xFF );
ppu.write_secondary_sprite_ram( 8, 0xFF );
ppu.write_secondary_sprite_ram( 9, 0xFF );
ppu.write_secondary_sprite_ram( 10, 0xFF );
ppu.write_secondary_sprite_ram( 11, 0xFF );
ppu.write_secondary_sprite_ram( 12, 0xFF );
ppu.write_secondary_sprite_ram( 13, 0xFF );
ppu.write_secondary_sprite_ram( 14, 0xFF );
ppu.write_secondary_sprite_ram( 15, 0xFF );
ppu.write_secondary_sprite_ram( 16, 0xFF );
ppu.write_secondary_sprite_ram( 17, 0xFF );
ppu.write_secondary_sprite_ram( 18, 0xFF );
ppu.write_secondary_sprite_ram( 19, 0xFF );
ppu.write_secondary_sprite_ram( 20, 0xFF );
ppu.write_secondary_sprite_ram( 21, 0xFF );
ppu.write_secondary_sprite_ram( 22, 0xFF );
ppu.write_secondary_sprite_ram( 23, 0xFF );
ppu.write_secondary_sprite_ram( 24, 0xFF );
ppu.write_secondary_sprite_ram( 25, 0xFF );
ppu.write_secondary_sprite_ram( 26, 0xFF );
ppu.write_secondary_sprite_ram( 27, 0xFF );
ppu.write_secondary_sprite_ram( 28, 0xFF );
ppu.write_secondary_sprite_ram( 29, 0xFF );
ppu.write_secondary_sprite_ram( 30, 0xFF );
ppu.write_secondary_sprite_ram( 31, 0xFF );
ppu.write_secondary_sprite_ram( 0, 0x00 );
ppu.write_secondary_sprite_ram( 1, 0xAA );
ppu.write_secondary_sprite_ram( 2, 0x00 );
ppu.write_secondary_sprite_ram( 3, 0x00 );
ppu.write_secondary_sprite_ram( 4, 0x00 );
ppu.write_secondary_sprite_ram( 5, 0xBA );
ppu.write_secondary_sprite_ram( 6, 0x40 );
ppu.write_secondary_sprite_ram( 7, 0x08 );
ppu.write_secondary_sprite_ram( 8, 0x00 );
ppu.write_secondary_sprite_ram( 9, 0xCA );
ppu.write_secondary_sprite_ram( 10, 0x80 );
ppu.write_secondary_sprite_ram( 11, 0x10 );
ppu.write_secondary_sprite_ram( 12, 0x00 );
ppu.write_secondary_sprite_ram( 13, 0xDA );
ppu.write_secondary_sprite_ram( 14, 0xC0 );
ppu.write_secondary_sprite_ram( 15, 0x18 );
assert_eq( ppu.get_current_address(), 0x1402 );
ppu.step_pixel(); // 000 257 -> 000 258
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 258 -> 000 259
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 259 -> 000 260
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 260 -> 000 261
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 261 -> 000 262
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 262 -> 000 263
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 263 -> 000 264
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 264 -> 000 265
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 265 -> 000 266
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 266 -> 000 267
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 267 -> 000 268
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 268 -> 000 269
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 269 -> 000 270
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 270 -> 000 271
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 271 -> 000 272
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 272 -> 000 273
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 273 -> 000 274
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 274 -> 000 275
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 275 -> 000 276
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 276 -> 000 277
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 277 -> 000 278
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 278 -> 000 279
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 279 -> 000 280
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 280 -> 000 281
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 281 -> 000 282
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 282 -> 000 283
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 283 -> 000 284
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 284 -> 000 285
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 285 -> 000 286
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 286 -> 000 287
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 287 -> 000 288
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 288 -> 000 289
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 289 -> 000 290
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 290 -> 000 291
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 291 -> 000 292
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 292 -> 000 293
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 293 -> 000 294
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 294 -> 000 295
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 295 -> 000 296
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 296 -> 000 297
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 297 -> 000 298
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 298 -> 000 299
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 299 -> 000 300
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 300 -> 000 301
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 301 -> 000 302
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 302 -> 000 303
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 303 -> 000 304
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 304 -> 000 305
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 305 -> 000 306
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 306 -> 000 307
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 307 -> 000 308
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 308 -> 000 309
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 309 -> 000 310
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 310 -> 000 311
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 311 -> 000 312
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 312 -> 000 313
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 313 -> 000 314
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 314 -> 000 315
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 315 -> 000 316
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 316 -> 000 317
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 317 -> 000 318
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 318 -> 000 319
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 319 -> 000 320
assert_eq( ppu.get_current_address(), 0x1000 );
ppu.step_pixel(); // 000 320 -> 000 321
ppu.step_scanline();
for _ in 0..257u32 {
ppu.step_pixel();
} // 001 256 -> 001 257
ppu.write_secondary_sprite_ram( 0, 0xFF );
ppu.write_secondary_sprite_ram( 1, 0xFF );
ppu.write_secondary_sprite_ram( 2, 0xFF );
ppu.write_secondary_sprite_ram( 3, 0xFF );
ppu.write_secondary_sprite_ram( 4, 0xFF );
ppu.write_secondary_sprite_ram( 5, 0xFF );
ppu.write_secondary_sprite_ram( 6, 0xFF );
ppu.write_secondary_sprite_ram( 7, 0xFF );
ppu.write_secondary_sprite_ram( 8, 0xFF );
ppu.write_secondary_sprite_ram( 9, 0xFF );
ppu.write_secondary_sprite_ram( 10, 0xFF );
ppu.write_secondary_sprite_ram( 11, 0xFF );
ppu.write_secondary_sprite_ram( 12, 0xFF );
ppu.write_secondary_sprite_ram( 13, 0xFF );
ppu.write_secondary_sprite_ram( 14, 0xFF );
ppu.write_secondary_sprite_ram( 15, 0xFF );
ppu.write_secondary_sprite_ram( 16, 0xFF );
ppu.write_secondary_sprite_ram( 17, 0xFF );
ppu.write_secondary_sprite_ram( 18, 0xFF );
ppu.write_secondary_sprite_ram( 19, 0xFF );
ppu.write_secondary_sprite_ram( 20, 0xFF );
ppu.write_secondary_sprite_ram( 21, 0xFF );
ppu.write_secondary_sprite_ram( 22, 0xFF );
ppu.write_secondary_sprite_ram( 23, 0xFF );
ppu.write_secondary_sprite_ram( 24, 0xFF );
ppu.write_secondary_sprite_ram( 25, 0xFF );
ppu.write_secondary_sprite_ram( 26, 0xFF );
ppu.write_secondary_sprite_ram( 27, 0xFF );
ppu.write_secondary_sprite_ram( 28, 0xFF );
ppu.write_secondary_sprite_ram( 29, 0xFF );
ppu.write_secondary_sprite_ram( 30, 0xFF );
ppu.write_secondary_sprite_ram( 31, 0xFF );
ppu.write_secondary_sprite_ram( 0, 0x00 );
ppu.write_secondary_sprite_ram( 1, 0xAA );
ppu.write_secondary_sprite_ram( 2, 0x00 );
ppu.write_secondary_sprite_ram( 3, 0x00 );
ppu.write_secondary_sprite_ram( 4, 0x00 );
ppu.write_secondary_sprite_ram( 5, 0xBA );
ppu.write_secondary_sprite_ram( 6, 0x40 );
ppu.write_secondary_sprite_ram( 7, 0x08 );
ppu.write_secondary_sprite_ram( 8, 0x00 );
ppu.write_secondary_sprite_ram( 9, 0xCA );
ppu.write_secondary_sprite_ram( 10, 0x80 );
ppu.write_secondary_sprite_ram( 11, 0x10 );
ppu.write_secondary_sprite_ram( 12, 0x00 );
ppu.write_secondary_sprite_ram( 13, 0xDA );
ppu.write_secondary_sprite_ram( 14, 0xC0 );
ppu.write_secondary_sprite_ram( 15, 0x18 );
assert_eq( ppu.get_current_address(), 0x2402 );
ppu.step_pixel(); // 001 257 -> 001 258
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 258 -> 001 259
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 259 -> 001 260
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 260 -> 001 261
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 261 -> 001 262
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 262 -> 001 263
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 263 -> 001 264
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 264 -> 001 265
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 265 -> 001 266
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 266 -> 001 267
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 267 -> 001 268
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 268 -> 001 269
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 269 -> 001 270
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 270 -> 001 271
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 271 -> 001 272
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 272 -> 001 273
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 273 -> 001 274
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 274 -> 001 275
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 275 -> 001 276
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 276 -> 001 277
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 277 -> 001 278
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 278 -> 001 279
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 279 -> 001 280
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 280 -> 001 281
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 281 -> 001 282
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 282 -> 001 283
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 283 -> 001 284
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 284 -> 001 285
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 285 -> 001 286
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 286 -> 001 287
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 287 -> 001 288
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 288 -> 001 289
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 289 -> 001 290
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 290 -> 001 291
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 291 -> 001 292
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 292 -> 001 293
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 293 -> 001 294
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 294 -> 001 295
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 295 -> 001 296
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 296 -> 001 297
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 297 -> 001 298
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 298 -> 001 299
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 299 -> 001 300
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 300 -> 001 301
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 301 -> 001 302
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 302 -> 001 303
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 303 -> 001 304
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 304 -> 001 305
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 305 -> 001 306
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 306 -> 001 307
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 307 -> 001 308
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 308 -> 001 309
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 309 -> 001 310
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 310 -> 001 311
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 311 -> 001 312
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 312 -> 001 313
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 313 -> 001 314
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 314 -> 001 315
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 315 -> 001 316
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 316 -> 001 317
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 317 -> 001 318
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 318 -> 001 319
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 319 -> 001 320
assert_eq( ppu.get_current_address(), 0x2000 );
ppu.step_pixel(); // 001 320 -> 001 321
ppu.step_scanline();
for _ in 0..257u32 {
ppu.step_pixel();
} // 002 256 -> 002 257
ppu.write_secondary_sprite_ram( 0, 0xFF );
ppu.write_secondary_sprite_ram( 1, 0xFF );
ppu.write_secondary_sprite_ram( 2, 0xFF );
ppu.write_secondary_sprite_ram( 3, 0xFF );
ppu.write_secondary_sprite_ram( 4, 0xFF );
ppu.write_secondary_sprite_ram( 5, 0xFF );
ppu.write_secondary_sprite_ram( 6, 0xFF );
ppu.write_secondary_sprite_ram( 7, 0xFF );
ppu.write_secondary_sprite_ram( 8, 0xFF );
ppu.write_secondary_sprite_ram( 9, 0xFF );
ppu.write_secondary_sprite_ram( 10, 0xFF );
ppu.write_secondary_sprite_ram( 11, 0xFF );
ppu.write_secondary_sprite_ram( 12, 0xFF );
ppu.write_secondary_sprite_ram( 13, 0xFF );
ppu.write_secondary_sprite_ram( 14, 0xFF );
ppu.write_secondary_sprite_ram( 15, 0xFF );
ppu.write_secondary_sprite_ram( 16, 0xFF );
ppu.write_secondary_sprite_ram( 17, 0xFF );
ppu.write_secondary_sprite_ram( 18, 0xFF );
ppu.write_secondary_sprite_ram( 19, 0xFF );
ppu.write_secondary_sprite_ram( 20, 0xFF );
ppu.write_secondary_sprite_ram( 21, 0xFF );
ppu.write_secondary_sprite_ram( 22, 0xFF );
ppu.write_secondary_sprite_ram( 23, 0xFF );
ppu.write_secondary_sprite_ram( 24, 0xFF );
ppu.write_secondary_sprite_ram( 25, 0xFF );
ppu.write_secondary_sprite_ram( 26, 0xFF );
ppu.write_secondary_sprite_ram( 27, 0xFF );
ppu.write_secondary_sprite_ram( 28, 0xFF );
ppu.write_secondary_sprite_ram( 29, 0xFF );
ppu.write_secondary_sprite_ram( 30, 0xFF );
ppu.write_secondary_sprite_ram( 31, 0xFF );
ppu.write_secondary_sprite_ram( 0, 0x00 );
ppu.write_secondary_sprite_ram( 1, 0xAA );
ppu.write_secondary_sprite_ram( 2, 0x00 );
ppu.write_secondary_sprite_ram( 3, 0x00 );
ppu.write_secondary_sprite_ram( 4, 0x00 );
ppu.write_secondary_sprite_ram( 5, 0xBA );
ppu.write_secondary_sprite_ram( 6, 0x40 );
ppu.write_secondary_sprite_ram( 7, 0x08 );
ppu.write_secondary_sprite_ram( 8, 0x00 );
ppu.write_secondary_sprite_ram( 9, 0xCA );
ppu.write_secondary_sprite_ram( 10, 0x80 );
ppu.write_secondary_sprite_ram( 11, 0x10 );
ppu.write_secondary_sprite_ram( 12, 0x00 );
ppu.write_secondary_sprite_ram( 13, 0xDA );
ppu.write_secondary_sprite_ram( 14, 0xC0 );
ppu.write_secondary_sprite_ram( 15, 0x18 );
assert_eq( ppu.get_current_address(), 0x3402 );
ppu.step_pixel(); // 002 257 -> 002 258
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 258 -> 002 259
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 259 -> 002 260
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 260 -> 002 261
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 261 -> 002 262
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 262 -> 002 263
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 263 -> 002 264
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 264 -> 002 265
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 265 -> 002 266
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 266 -> 002 267
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 267 -> 002 268
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 268 -> 002 269
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 269 -> 002 270
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 270 -> 002 271
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 271 -> 002 272
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 272 -> 002 273
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 273 -> 002 274
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 274 -> 002 275
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 275 -> 002 276
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 276 -> 002 277
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 277 -> 002 278
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 278 -> 002 279
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 279 -> 002 280
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 280 -> 002 281
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 281 -> 002 282
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 282 -> 002 283
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 283 -> 002 284
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 284 -> 002 285
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 285 -> 002 286
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 286 -> 002 287
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 287 -> 002 288
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 288 -> 002 289
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 289 -> 002 290
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 290 -> 002 291
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 291 -> 002 292
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 292 -> 002 293
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 293 -> 002 294
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 294 -> 002 295
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 295 -> 002 296
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 296 -> 002 297
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 297 -> 002 298
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 298 -> 002 299
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 299 -> 002 300
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 300 -> 002 301
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 301 -> 002 302
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 302 -> 002 303
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 303 -> 002 304
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 304 -> 002 305
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 305 -> 002 306
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 306 -> 002 307
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 307 -> 002 308
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 308 -> 002 309
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 309 -> 002 310
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 310 -> 002 311
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 311 -> 002 312
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 312 -> 002 313
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 313 -> 002 314
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 314 -> 002 315
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 315 -> 002 316
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 316 -> 002 317
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 317 -> 002 318
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 318 -> 002 319
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 319 -> 002 320
assert_eq( ppu.get_current_address(), 0x3000 );
ppu.step_pixel(); // 002 320 -> 002 321
ppu.step_scanline();
assert_eq!( ppu.scanline(), 3 );
assert_eq!( ppu.dot(), 0 );
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,584 @@
// This file was AUTOGENERATED; do not edit!
#[allow(unused_imports)]
use super::super::assert_eq;
use TestPPU;
#[inline(never)]
pub fn test_vram_access_during_background_rendering( ppu: &mut TestPPU ) {
assert_eq!( ppu.scanline(), 261 );
assert_eq!( ppu.dot(), 0 );
for i in 0..4096u32 {
ppu.write_vram( i as u16, (i + 0x80) as u8 );
}
for i in 0..960u32 {
ppu.write_vram( (0x2000 + i) as u16, (i + 0x80) as u8 );
}
for i in 0..64u32 {
ppu.write_vram( (0x2000 + 960 + i) as u16, (0x80 | i) as u8 );
}
ppu.write_ioreg( 1, 0x0A );
ppu.step_pixel(); // 261 000 -> 261 001
ppu.step_pixel(); // 261 001 -> 261 002
ppu.step_pixel(); // 261 002 -> 261 003
ppu.step_scanline();
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 000 -> 000 001
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 001 -> 000 002
ppu.expect_vram_read( 0x2002, 0x82 );
ppu.step_pixel(); // 000 002 -> 000 003
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 003 -> 000 004
ppu.expect_vram_read( 0x23C0, 0x80 );
ppu.step_pixel(); // 000 004 -> 000 005
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 005 -> 000 006
ppu.expect_vram_read( 0x0820, 0xA0 );
ppu.step_pixel(); // 000 006 -> 000 007
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 007 -> 000 008
ppu.expect_vram_read( 0x0828, 0xA8 );
ppu.step_pixel(); // 000 008 -> 000 009
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 009 -> 000 010
ppu.expect_vram_read( 0x2003, 0x83 );
ppu.step_pixel(); // 000 010 -> 000 011
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 011 -> 000 012
ppu.expect_vram_read( 0x23C0, 0x80 );
ppu.step_pixel(); // 000 012 -> 000 013
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 013 -> 000 014
ppu.expect_vram_read( 0x0830, 0xB0 );
ppu.step_pixel(); // 000 014 -> 000 015
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 015 -> 000 016
ppu.expect_vram_read( 0x0838, 0xB8 );
ppu.step_pixel(); // 000 016 -> 000 017
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 017 -> 000 018
ppu.expect_vram_read( 0x2004, 0x84 );
ppu.step_pixel(); // 000 018 -> 000 019
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 019 -> 000 020
ppu.expect_vram_read( 0x23C1, 0x81 );
ppu.step_pixel(); // 000 020 -> 000 021
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 021 -> 000 022
ppu.expect_vram_read( 0x0840, 0xC0 );
ppu.step_pixel(); // 000 022 -> 000 023
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 023 -> 000 024
ppu.expect_vram_read( 0x0848, 0xC8 );
ppu.step_pixel(); // 000 024 -> 000 025
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 025 -> 000 026
ppu.expect_vram_read( 0x2005, 0x85 );
ppu.step_pixel(); // 000 026 -> 000 027
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 027 -> 000 028
ppu.expect_vram_read( 0x23C1, 0x81 );
ppu.step_pixel(); // 000 028 -> 000 029
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 029 -> 000 030
ppu.expect_vram_read( 0x0850, 0xD0 );
ppu.step_pixel(); // 000 030 -> 000 031
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 031 -> 000 032
ppu.expect_vram_read( 0x0858, 0xD8 );
ppu.step_pixel(); // 000 032 -> 000 033
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 033 -> 000 034
ppu.expect_vram_read( 0x2006, 0x86 );
ppu.step_pixel(); // 000 034 -> 000 035
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 035 -> 000 036
ppu.expect_vram_read( 0x23C1, 0x81 );
ppu.step_pixel(); // 000 036 -> 000 037
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 037 -> 000 038
ppu.expect_vram_read( 0x0860, 0xE0 );
ppu.step_pixel(); // 000 038 -> 000 039
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 039 -> 000 040
ppu.expect_vram_read( 0x0868, 0xE8 );
ppu.step_pixel(); // 000 040 -> 000 041
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 041 -> 000 042
ppu.expect_vram_read( 0x2007, 0x87 );
ppu.step_pixel(); // 000 042 -> 000 043
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 043 -> 000 044
ppu.expect_vram_read( 0x23C1, 0x81 );
ppu.step_pixel(); // 000 044 -> 000 045
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 045 -> 000 046
ppu.expect_vram_read( 0x0870, 0xF0 );
ppu.step_pixel(); // 000 046 -> 000 047
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 047 -> 000 048
ppu.expect_vram_read( 0x0878, 0xF8 );
ppu.step_pixel(); // 000 048 -> 000 049
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 049 -> 000 050
ppu.expect_vram_read( 0x2008, 0x88 );
ppu.step_pixel(); // 000 050 -> 000 051
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 051 -> 000 052
ppu.expect_vram_read( 0x23C2, 0x82 );
ppu.step_pixel(); // 000 052 -> 000 053
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 053 -> 000 054
ppu.expect_vram_read( 0x0880, 0x00 );
ppu.step_pixel(); // 000 054 -> 000 055
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 055 -> 000 056
ppu.expect_vram_read( 0x0888, 0x08 );
ppu.step_pixel(); // 000 056 -> 000 057
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 057 -> 000 058
ppu.expect_vram_read( 0x2009, 0x89 );
ppu.step_pixel(); // 000 058 -> 000 059
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 059 -> 000 060
ppu.expect_vram_read( 0x23C2, 0x82 );
ppu.step_pixel(); // 000 060 -> 000 061
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 061 -> 000 062
ppu.expect_vram_read( 0x0890, 0x10 );
ppu.step_pixel(); // 000 062 -> 000 063
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 063 -> 000 064
ppu.expect_vram_read( 0x0898, 0x18 );
ppu.step_pixel(); // 000 064 -> 000 065
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 065 -> 000 066
ppu.expect_vram_read( 0x200A, 0x8A );
ppu.step_pixel(); // 000 066 -> 000 067
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 067 -> 000 068
ppu.expect_vram_read( 0x23C2, 0x82 );
ppu.step_pixel(); // 000 068 -> 000 069
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 069 -> 000 070
ppu.expect_vram_read( 0x08A0, 0x20 );
ppu.step_pixel(); // 000 070 -> 000 071
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 071 -> 000 072
ppu.expect_vram_read( 0x08A8, 0x28 );
ppu.step_pixel(); // 000 072 -> 000 073
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 073 -> 000 074
ppu.expect_vram_read( 0x200B, 0x8B );
ppu.step_pixel(); // 000 074 -> 000 075
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 075 -> 000 076
ppu.expect_vram_read( 0x23C2, 0x82 );
ppu.step_pixel(); // 000 076 -> 000 077
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 077 -> 000 078
ppu.expect_vram_read( 0x08B0, 0x30 );
ppu.step_pixel(); // 000 078 -> 000 079
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 079 -> 000 080
ppu.expect_vram_read( 0x08B8, 0x38 );
ppu.step_pixel(); // 000 080 -> 000 081
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 081 -> 000 082
ppu.expect_vram_read( 0x200C, 0x8C );
ppu.step_pixel(); // 000 082 -> 000 083
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 083 -> 000 084
ppu.expect_vram_read( 0x23C3, 0x83 );
ppu.step_pixel(); // 000 084 -> 000 085
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 085 -> 000 086
ppu.expect_vram_read( 0x08C0, 0x40 );
ppu.step_pixel(); // 000 086 -> 000 087
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 087 -> 000 088
ppu.expect_vram_read( 0x08C8, 0x48 );
ppu.step_pixel(); // 000 088 -> 000 089
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 089 -> 000 090
ppu.expect_vram_read( 0x200D, 0x8D );
ppu.step_pixel(); // 000 090 -> 000 091
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 091 -> 000 092
ppu.expect_vram_read( 0x23C3, 0x83 );
ppu.step_pixel(); // 000 092 -> 000 093
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 093 -> 000 094
ppu.expect_vram_read( 0x08D0, 0x50 );
ppu.step_pixel(); // 000 094 -> 000 095
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 095 -> 000 096
ppu.expect_vram_read( 0x08D8, 0x58 );
ppu.step_pixel(); // 000 096 -> 000 097
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 097 -> 000 098
ppu.expect_vram_read( 0x200E, 0x8E );
ppu.step_pixel(); // 000 098 -> 000 099
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 099 -> 000 100
ppu.expect_vram_read( 0x23C3, 0x83 );
ppu.step_pixel(); // 000 100 -> 000 101
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 101 -> 000 102
ppu.expect_vram_read( 0x08E0, 0x60 );
ppu.step_pixel(); // 000 102 -> 000 103
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 103 -> 000 104
ppu.expect_vram_read( 0x08E8, 0x68 );
ppu.step_pixel(); // 000 104 -> 000 105
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 105 -> 000 106
ppu.expect_vram_read( 0x200F, 0x8F );
ppu.step_pixel(); // 000 106 -> 000 107
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 107 -> 000 108
ppu.expect_vram_read( 0x23C3, 0x83 );
ppu.step_pixel(); // 000 108 -> 000 109
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 109 -> 000 110
ppu.expect_vram_read( 0x08F0, 0x70 );
ppu.step_pixel(); // 000 110 -> 000 111
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 111 -> 000 112
ppu.expect_vram_read( 0x08F8, 0x78 );
ppu.step_pixel(); // 000 112 -> 000 113
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 113 -> 000 114
ppu.expect_vram_read( 0x2010, 0x90 );
ppu.step_pixel(); // 000 114 -> 000 115
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 115 -> 000 116
ppu.expect_vram_read( 0x23C4, 0x84 );
ppu.step_pixel(); // 000 116 -> 000 117
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 117 -> 000 118
ppu.expect_vram_read( 0x0900, 0x80 );
ppu.step_pixel(); // 000 118 -> 000 119
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 119 -> 000 120
ppu.expect_vram_read( 0x0908, 0x88 );
ppu.step_pixel(); // 000 120 -> 000 121
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 121 -> 000 122
ppu.expect_vram_read( 0x2011, 0x91 );
ppu.step_pixel(); // 000 122 -> 000 123
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 123 -> 000 124
ppu.expect_vram_read( 0x23C4, 0x84 );
ppu.step_pixel(); // 000 124 -> 000 125
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 125 -> 000 126
ppu.expect_vram_read( 0x0910, 0x90 );
ppu.step_pixel(); // 000 126 -> 000 127
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 127 -> 000 128
ppu.expect_vram_read( 0x0918, 0x98 );
ppu.step_pixel(); // 000 128 -> 000 129
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 129 -> 000 130
ppu.expect_vram_read( 0x2012, 0x92 );
ppu.step_pixel(); // 000 130 -> 000 131
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 131 -> 000 132
ppu.expect_vram_read( 0x23C4, 0x84 );
ppu.step_pixel(); // 000 132 -> 000 133
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 133 -> 000 134
ppu.expect_vram_read( 0x0920, 0xA0 );
ppu.step_pixel(); // 000 134 -> 000 135
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 135 -> 000 136
ppu.expect_vram_read( 0x0928, 0xA8 );
ppu.step_pixel(); // 000 136 -> 000 137
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 137 -> 000 138
ppu.expect_vram_read( 0x2013, 0x93 );
ppu.step_pixel(); // 000 138 -> 000 139
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 139 -> 000 140
ppu.expect_vram_read( 0x23C4, 0x84 );
ppu.step_pixel(); // 000 140 -> 000 141
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 141 -> 000 142
ppu.expect_vram_read( 0x0930, 0xB0 );
ppu.step_pixel(); // 000 142 -> 000 143
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 143 -> 000 144
ppu.expect_vram_read( 0x0938, 0xB8 );
ppu.step_pixel(); // 000 144 -> 000 145
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 145 -> 000 146
ppu.expect_vram_read( 0x2014, 0x94 );
ppu.step_pixel(); // 000 146 -> 000 147
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 147 -> 000 148
ppu.expect_vram_read( 0x23C5, 0x85 );
ppu.step_pixel(); // 000 148 -> 000 149
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 149 -> 000 150
ppu.expect_vram_read( 0x0940, 0xC0 );
ppu.step_pixel(); // 000 150 -> 000 151
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 151 -> 000 152
ppu.expect_vram_read( 0x0948, 0xC8 );
ppu.step_pixel(); // 000 152 -> 000 153
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 153 -> 000 154
ppu.expect_vram_read( 0x2015, 0x95 );
ppu.step_pixel(); // 000 154 -> 000 155
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 155 -> 000 156
ppu.expect_vram_read( 0x23C5, 0x85 );
ppu.step_pixel(); // 000 156 -> 000 157
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 157 -> 000 158
ppu.expect_vram_read( 0x0950, 0xD0 );
ppu.step_pixel(); // 000 158 -> 000 159
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 159 -> 000 160
ppu.expect_vram_read( 0x0958, 0xD8 );
ppu.step_pixel(); // 000 160 -> 000 161
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 161 -> 000 162
ppu.expect_vram_read( 0x2016, 0x96 );
ppu.step_pixel(); // 000 162 -> 000 163
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 163 -> 000 164
ppu.expect_vram_read( 0x23C5, 0x85 );
ppu.step_pixel(); // 000 164 -> 000 165
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 165 -> 000 166
ppu.expect_vram_read( 0x0960, 0xE0 );
ppu.step_pixel(); // 000 166 -> 000 167
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 167 -> 000 168
ppu.expect_vram_read( 0x0968, 0xE8 );
ppu.step_pixel(); // 000 168 -> 000 169
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 169 -> 000 170
ppu.expect_vram_read( 0x2017, 0x97 );
ppu.step_pixel(); // 000 170 -> 000 171
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 171 -> 000 172
ppu.expect_vram_read( 0x23C5, 0x85 );
ppu.step_pixel(); // 000 172 -> 000 173
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 173 -> 000 174
ppu.expect_vram_read( 0x0970, 0xF0 );
ppu.step_pixel(); // 000 174 -> 000 175
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 175 -> 000 176
ppu.expect_vram_read( 0x0978, 0xF8 );
ppu.step_pixel(); // 000 176 -> 000 177
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 177 -> 000 178
ppu.expect_vram_read( 0x2018, 0x98 );
ppu.step_pixel(); // 000 178 -> 000 179
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 179 -> 000 180
ppu.expect_vram_read( 0x23C6, 0x86 );
ppu.step_pixel(); // 000 180 -> 000 181
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 181 -> 000 182
ppu.expect_vram_read( 0x0980, 0x00 );
ppu.step_pixel(); // 000 182 -> 000 183
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 183 -> 000 184
ppu.expect_vram_read( 0x0988, 0x08 );
ppu.step_pixel(); // 000 184 -> 000 185
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 185 -> 000 186
ppu.expect_vram_read( 0x2019, 0x99 );
ppu.step_pixel(); // 000 186 -> 000 187
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 187 -> 000 188
ppu.expect_vram_read( 0x23C6, 0x86 );
ppu.step_pixel(); // 000 188 -> 000 189
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 189 -> 000 190
ppu.expect_vram_read( 0x0990, 0x10 );
ppu.step_pixel(); // 000 190 -> 000 191
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 191 -> 000 192
ppu.expect_vram_read( 0x0998, 0x18 );
ppu.step_pixel(); // 000 192 -> 000 193
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 193 -> 000 194
ppu.expect_vram_read( 0x201A, 0x9A );
ppu.step_pixel(); // 000 194 -> 000 195
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 195 -> 000 196
ppu.expect_vram_read( 0x23C6, 0x86 );
ppu.step_pixel(); // 000 196 -> 000 197
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 197 -> 000 198
ppu.expect_vram_read( 0x09A0, 0x20 );
ppu.step_pixel(); // 000 198 -> 000 199
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 199 -> 000 200
ppu.expect_vram_read( 0x09A8, 0x28 );
ppu.step_pixel(); // 000 200 -> 000 201
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 201 -> 000 202
ppu.expect_vram_read( 0x201B, 0x9B );
ppu.step_pixel(); // 000 202 -> 000 203
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 203 -> 000 204
ppu.expect_vram_read( 0x23C6, 0x86 );
ppu.step_pixel(); // 000 204 -> 000 205
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 205 -> 000 206
ppu.expect_vram_read( 0x09B0, 0x30 );
ppu.step_pixel(); // 000 206 -> 000 207
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 207 -> 000 208
ppu.expect_vram_read( 0x09B8, 0x38 );
ppu.step_pixel(); // 000 208 -> 000 209
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 209 -> 000 210
ppu.expect_vram_read( 0x201C, 0x9C );
ppu.step_pixel(); // 000 210 -> 000 211
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 211 -> 000 212
ppu.expect_vram_read( 0x23C7, 0x87 );
ppu.step_pixel(); // 000 212 -> 000 213
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 213 -> 000 214
ppu.expect_vram_read( 0x09C0, 0x40 );
ppu.step_pixel(); // 000 214 -> 000 215
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 215 -> 000 216
ppu.expect_vram_read( 0x09C8, 0x48 );
ppu.step_pixel(); // 000 216 -> 000 217
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 217 -> 000 218
ppu.expect_vram_read( 0x201D, 0x9D );
ppu.step_pixel(); // 000 218 -> 000 219
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 219 -> 000 220
ppu.expect_vram_read( 0x23C7, 0x87 );
ppu.step_pixel(); // 000 220 -> 000 221
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 221 -> 000 222
ppu.expect_vram_read( 0x09D0, 0x50 );
ppu.step_pixel(); // 000 222 -> 000 223
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 223 -> 000 224
ppu.expect_vram_read( 0x09D8, 0x58 );
ppu.step_pixel(); // 000 224 -> 000 225
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 225 -> 000 226
ppu.expect_vram_read( 0x201E, 0x9E );
ppu.step_pixel(); // 000 226 -> 000 227
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 227 -> 000 228
ppu.expect_vram_read( 0x23C7, 0x87 );
ppu.step_pixel(); // 000 228 -> 000 229
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 229 -> 000 230
ppu.expect_vram_read( 0x09E0, 0x60 );
ppu.step_pixel(); // 000 230 -> 000 231
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 231 -> 000 232
ppu.expect_vram_read( 0x09E8, 0x68 );
ppu.step_pixel(); // 000 232 -> 000 233
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 233 -> 000 234
ppu.expect_vram_read( 0x201F, 0x9F );
ppu.step_pixel(); // 000 234 -> 000 235
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 235 -> 000 236
ppu.expect_vram_read( 0x23C7, 0x87 );
ppu.step_pixel(); // 000 236 -> 000 237
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 237 -> 000 238
ppu.expect_vram_read( 0x09F0, 0x70 );
ppu.step_pixel(); // 000 238 -> 000 239
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 239 -> 000 240
ppu.expect_vram_read( 0x09F8, 0x78 );
ppu.step_pixel(); // 000 240 -> 000 241
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 241 -> 000 242
ppu.expect_vram_read( 0x2400, 0x80 );
ppu.step_pixel(); // 000 242 -> 000 243
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 243 -> 000 244
ppu.expect_vram_read( 0x27C0, 0x80 );
ppu.step_pixel(); // 000 244 -> 000 245
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 245 -> 000 246
ppu.expect_vram_read( 0x0800, 0x80 );
ppu.step_pixel(); // 000 246 -> 000 247
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 247 -> 000 248
ppu.expect_vram_read( 0x0808, 0x88 );
ppu.step_pixel(); // 000 248 -> 000 249
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 249 -> 000 250
ppu.expect_vram_read( 0x2401, 0x81 );
ppu.step_pixel(); // 000 250 -> 000 251
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 251 -> 000 252
ppu.expect_vram_read( 0x27C0, 0x80 );
ppu.step_pixel(); // 000 252 -> 000 253
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 253 -> 000 254
ppu.expect_vram_read( 0x0810, 0x90 );
ppu.step_pixel(); // 000 254 -> 000 255
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 255 -> 000 256
ppu.expect_vram_read( 0x0818, 0x98 );
ppu.step_pixel(); // 000 256 -> 000 257
for _ in 0..64u32 {
ppu.step_pixel();
} // 000 320 -> 000 321
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 321 -> 000 322
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 322 -> 000 323
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 323 -> 000 324
ppu.expect_vram_read( 0x23C0, 0x80 );
ppu.step_pixel(); // 000 324 -> 000 325
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 325 -> 000 326
ppu.expect_vram_read( 0x0801, 0x81 );
ppu.step_pixel(); // 000 326 -> 000 327
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 327 -> 000 328
ppu.expect_vram_read( 0x0809, 0x89 );
ppu.step_pixel(); // 000 328 -> 000 329
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 329 -> 000 330
ppu.expect_vram_read( 0x2001, 0x81 );
ppu.step_pixel(); // 000 330 -> 000 331
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 331 -> 000 332
ppu.expect_vram_read( 0x23C0, 0x80 );
ppu.step_pixel(); // 000 332 -> 000 333
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 333 -> 000 334
ppu.expect_vram_read( 0x0811, 0x91 );
ppu.step_pixel(); // 000 334 -> 000 335
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 335 -> 000 336
ppu.expect_vram_read( 0x0819, 0x99 );
ppu.step_pixel(); // 000 336 -> 000 337
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 337 -> 000 338
ppu.expect_vram_read( 0x2002, 0x82 );
ppu.step_pixel(); // 000 338 -> 000 339
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 339 -> 000 340
ppu.expect_vram_read( 0x2002, 0x82 );
ppu.step_pixel(); // 000 340 -> 001 000
assert_eq!( ppu.scanline(), 1 );
assert_eq!( ppu.dot(), 0 );
}

View file

@ -0,0 +1,567 @@
// This file was AUTOGENERATED; do not edit!
#[allow(unused_imports)]
use super::super::assert_eq;
use TestPPU;
#[inline(never)]
pub fn test_vram_access_during_sprite_rendering( ppu: &mut TestPPU ) {
assert_eq!( ppu.scanline(), 261 );
assert_eq!( ppu.dot(), 0 );
for i in 0..4096u32 {
ppu.write_vram( i as u16, (i + 0x80) as u8 );
}
for i in 0..960u32 {
ppu.write_vram( (0x2000 + i) as u16, (i + 0x80) as u8 );
}
for i in 0..64u32 {
ppu.write_vram( (0x2000 + 960 + i) as u16, (0x80 | i) as u8 );
}
ppu.write_ioreg( 1, 0x14 );
ppu.step_pixel(); // 261 000 -> 261 001
ppu.step_pixel(); // 261 001 -> 261 002
ppu.step_pixel(); // 261 002 -> 261 003
ppu.step_scanline();
for _ in 0..257u32 {
ppu.step_pixel();
} // 000 256 -> 000 257
ppu.write_secondary_sprite_ram( 0, 0xFF );
ppu.write_secondary_sprite_ram( 1, 0xFF );
ppu.write_secondary_sprite_ram( 2, 0xFF );
ppu.write_secondary_sprite_ram( 3, 0xFF );
ppu.write_secondary_sprite_ram( 4, 0xFF );
ppu.write_secondary_sprite_ram( 5, 0xFF );
ppu.write_secondary_sprite_ram( 6, 0xFF );
ppu.write_secondary_sprite_ram( 7, 0xFF );
ppu.write_secondary_sprite_ram( 8, 0xFF );
ppu.write_secondary_sprite_ram( 9, 0xFF );
ppu.write_secondary_sprite_ram( 10, 0xFF );
ppu.write_secondary_sprite_ram( 11, 0xFF );
ppu.write_secondary_sprite_ram( 12, 0xFF );
ppu.write_secondary_sprite_ram( 13, 0xFF );
ppu.write_secondary_sprite_ram( 14, 0xFF );
ppu.write_secondary_sprite_ram( 15, 0xFF );
ppu.write_secondary_sprite_ram( 16, 0xFF );
ppu.write_secondary_sprite_ram( 17, 0xFF );
ppu.write_secondary_sprite_ram( 18, 0xFF );
ppu.write_secondary_sprite_ram( 19, 0xFF );
ppu.write_secondary_sprite_ram( 20, 0xFF );
ppu.write_secondary_sprite_ram( 21, 0xFF );
ppu.write_secondary_sprite_ram( 22, 0xFF );
ppu.write_secondary_sprite_ram( 23, 0xFF );
ppu.write_secondary_sprite_ram( 24, 0xFF );
ppu.write_secondary_sprite_ram( 25, 0xFF );
ppu.write_secondary_sprite_ram( 26, 0xFF );
ppu.write_secondary_sprite_ram( 27, 0xFF );
ppu.write_secondary_sprite_ram( 28, 0xFF );
ppu.write_secondary_sprite_ram( 29, 0xFF );
ppu.write_secondary_sprite_ram( 30, 0xFF );
ppu.write_secondary_sprite_ram( 31, 0xFF );
ppu.write_secondary_sprite_ram( 0, 0x00 );
ppu.write_secondary_sprite_ram( 1, 0xAA );
ppu.write_secondary_sprite_ram( 2, 0x00 );
ppu.write_secondary_sprite_ram( 3, 0x00 );
ppu.write_secondary_sprite_ram( 4, 0x00 );
ppu.write_secondary_sprite_ram( 5, 0xBA );
ppu.write_secondary_sprite_ram( 6, 0x40 );
ppu.write_secondary_sprite_ram( 7, 0x08 );
ppu.write_secondary_sprite_ram( 8, 0x00 );
ppu.write_secondary_sprite_ram( 9, 0xCA );
ppu.write_secondary_sprite_ram( 10, 0x80 );
ppu.write_secondary_sprite_ram( 11, 0x10 );
ppu.write_secondary_sprite_ram( 12, 0x00 );
ppu.write_secondary_sprite_ram( 13, 0xDA );
ppu.write_secondary_sprite_ram( 14, 0xC0 );
ppu.write_secondary_sprite_ram( 15, 0x18 );
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 257 -> 000 258
ppu.expect_vram_read( 0x2402, 0x82 );
ppu.step_pixel(); // 000 258 -> 000 259
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 259 -> 000 260
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 260 -> 000 261
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 261 -> 000 262
ppu.expect_vram_read( 0x0AA0, 0x20 );
ppu.step_pixel(); // 000 262 -> 000 263
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 263 -> 000 264
ppu.expect_vram_read( 0x0AA8, 0x28 );
ppu.step_pixel(); // 000 264 -> 000 265
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 265 -> 000 266
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 266 -> 000 267
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 267 -> 000 268
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 268 -> 000 269
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 269 -> 000 270
ppu.expect_vram_read( 0x0BA0, 0x20 );
ppu.step_pixel(); // 000 270 -> 000 271
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 271 -> 000 272
ppu.expect_vram_read( 0x0BA8, 0x28 );
ppu.step_pixel(); // 000 272 -> 000 273
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 273 -> 000 274
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 274 -> 000 275
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 275 -> 000 276
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 276 -> 000 277
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 277 -> 000 278
ppu.expect_vram_read( 0x0CA7, 0x27 );
ppu.step_pixel(); // 000 278 -> 000 279
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 279 -> 000 280
ppu.expect_vram_read( 0x0CAF, 0x2F );
ppu.step_pixel(); // 000 280 -> 000 281
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 281 -> 000 282
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 282 -> 000 283
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 283 -> 000 284
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 284 -> 000 285
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 285 -> 000 286
ppu.expect_vram_read( 0x0DA7, 0x27 );
ppu.step_pixel(); // 000 286 -> 000 287
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 287 -> 000 288
ppu.expect_vram_read( 0x0DAF, 0x2F );
ppu.step_pixel(); // 000 288 -> 000 289
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 289 -> 000 290
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 290 -> 000 291
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 291 -> 000 292
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 292 -> 000 293
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 293 -> 000 294
ppu.expect_vram_read( 0x0FF6, 0x76 );
ppu.step_pixel(); // 000 294 -> 000 295
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 295 -> 000 296
ppu.expect_vram_read( 0x0FFE, 0x7E );
ppu.step_pixel(); // 000 296 -> 000 297
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 297 -> 000 298
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 298 -> 000 299
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 299 -> 000 300
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 300 -> 000 301
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 301 -> 000 302
ppu.expect_vram_read( 0x0FF6, 0x76 );
ppu.step_pixel(); // 000 302 -> 000 303
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 303 -> 000 304
ppu.expect_vram_read( 0x0FFE, 0x7E );
ppu.step_pixel(); // 000 304 -> 000 305
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 305 -> 000 306
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 306 -> 000 307
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 307 -> 000 308
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 308 -> 000 309
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 309 -> 000 310
ppu.expect_vram_read( 0x0FF6, 0x76 );
ppu.step_pixel(); // 000 310 -> 000 311
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 311 -> 000 312
ppu.expect_vram_read( 0x0FFE, 0x7E );
ppu.step_pixel(); // 000 312 -> 000 313
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 313 -> 000 314
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 314 -> 000 315
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 315 -> 000 316
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 000 316 -> 000 317
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 317 -> 000 318
ppu.expect_vram_read( 0x0FF6, 0x76 );
ppu.step_pixel(); // 000 318 -> 000 319
ppu.expect_no_vram_read();
ppu.step_pixel(); // 000 319 -> 000 320
ppu.expect_vram_read( 0x0FFE, 0x7E );
ppu.step_pixel(); // 000 320 -> 000 321
ppu.step_scanline();
for _ in 0..257u32 {
ppu.step_pixel();
} // 001 256 -> 001 257
ppu.write_secondary_sprite_ram( 0, 0xFF );
ppu.write_secondary_sprite_ram( 1, 0xFF );
ppu.write_secondary_sprite_ram( 2, 0xFF );
ppu.write_secondary_sprite_ram( 3, 0xFF );
ppu.write_secondary_sprite_ram( 4, 0xFF );
ppu.write_secondary_sprite_ram( 5, 0xFF );
ppu.write_secondary_sprite_ram( 6, 0xFF );
ppu.write_secondary_sprite_ram( 7, 0xFF );
ppu.write_secondary_sprite_ram( 8, 0xFF );
ppu.write_secondary_sprite_ram( 9, 0xFF );
ppu.write_secondary_sprite_ram( 10, 0xFF );
ppu.write_secondary_sprite_ram( 11, 0xFF );
ppu.write_secondary_sprite_ram( 12, 0xFF );
ppu.write_secondary_sprite_ram( 13, 0xFF );
ppu.write_secondary_sprite_ram( 14, 0xFF );
ppu.write_secondary_sprite_ram( 15, 0xFF );
ppu.write_secondary_sprite_ram( 16, 0xFF );
ppu.write_secondary_sprite_ram( 17, 0xFF );
ppu.write_secondary_sprite_ram( 18, 0xFF );
ppu.write_secondary_sprite_ram( 19, 0xFF );
ppu.write_secondary_sprite_ram( 20, 0xFF );
ppu.write_secondary_sprite_ram( 21, 0xFF );
ppu.write_secondary_sprite_ram( 22, 0xFF );
ppu.write_secondary_sprite_ram( 23, 0xFF );
ppu.write_secondary_sprite_ram( 24, 0xFF );
ppu.write_secondary_sprite_ram( 25, 0xFF );
ppu.write_secondary_sprite_ram( 26, 0xFF );
ppu.write_secondary_sprite_ram( 27, 0xFF );
ppu.write_secondary_sprite_ram( 28, 0xFF );
ppu.write_secondary_sprite_ram( 29, 0xFF );
ppu.write_secondary_sprite_ram( 30, 0xFF );
ppu.write_secondary_sprite_ram( 31, 0xFF );
ppu.write_secondary_sprite_ram( 0, 0x00 );
ppu.write_secondary_sprite_ram( 1, 0xAA );
ppu.write_secondary_sprite_ram( 2, 0x00 );
ppu.write_secondary_sprite_ram( 3, 0x00 );
ppu.write_secondary_sprite_ram( 4, 0x00 );
ppu.write_secondary_sprite_ram( 5, 0xBA );
ppu.write_secondary_sprite_ram( 6, 0x40 );
ppu.write_secondary_sprite_ram( 7, 0x08 );
ppu.write_secondary_sprite_ram( 8, 0x00 );
ppu.write_secondary_sprite_ram( 9, 0xCA );
ppu.write_secondary_sprite_ram( 10, 0x80 );
ppu.write_secondary_sprite_ram( 11, 0x10 );
ppu.write_secondary_sprite_ram( 12, 0x00 );
ppu.write_secondary_sprite_ram( 13, 0xDA );
ppu.write_secondary_sprite_ram( 14, 0xC0 );
ppu.write_secondary_sprite_ram( 15, 0x18 );
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 257 -> 001 258
ppu.expect_vram_read( 0x2402, 0x82 );
ppu.step_pixel(); // 001 258 -> 001 259
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 259 -> 001 260
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 260 -> 001 261
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 261 -> 001 262
ppu.expect_vram_read( 0x0AA1, 0x21 );
ppu.step_pixel(); // 001 262 -> 001 263
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 263 -> 001 264
ppu.expect_vram_read( 0x0AA9, 0x29 );
ppu.step_pixel(); // 001 264 -> 001 265
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 265 -> 001 266
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 266 -> 001 267
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 267 -> 001 268
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 268 -> 001 269
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 269 -> 001 270
ppu.expect_vram_read( 0x0BA1, 0x21 );
ppu.step_pixel(); // 001 270 -> 001 271
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 271 -> 001 272
ppu.expect_vram_read( 0x0BA9, 0x29 );
ppu.step_pixel(); // 001 272 -> 001 273
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 273 -> 001 274
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 274 -> 001 275
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 275 -> 001 276
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 276 -> 001 277
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 277 -> 001 278
ppu.expect_vram_read( 0x0CA6, 0x26 );
ppu.step_pixel(); // 001 278 -> 001 279
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 279 -> 001 280
ppu.expect_vram_read( 0x0CAE, 0x2E );
ppu.step_pixel(); // 001 280 -> 001 281
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 281 -> 001 282
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 282 -> 001 283
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 283 -> 001 284
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 284 -> 001 285
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 285 -> 001 286
ppu.expect_vram_read( 0x0DA6, 0x26 );
ppu.step_pixel(); // 001 286 -> 001 287
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 287 -> 001 288
ppu.expect_vram_read( 0x0DAE, 0x2E );
ppu.step_pixel(); // 001 288 -> 001 289
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 289 -> 001 290
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 290 -> 001 291
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 291 -> 001 292
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 292 -> 001 293
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 293 -> 001 294
ppu.expect_vram_read( 0x0FF5, 0x75 );
ppu.step_pixel(); // 001 294 -> 001 295
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 295 -> 001 296
ppu.expect_vram_read( 0x0FFD, 0x7D );
ppu.step_pixel(); // 001 296 -> 001 297
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 297 -> 001 298
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 298 -> 001 299
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 299 -> 001 300
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 300 -> 001 301
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 301 -> 001 302
ppu.expect_vram_read( 0x0FF5, 0x75 );
ppu.step_pixel(); // 001 302 -> 001 303
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 303 -> 001 304
ppu.expect_vram_read( 0x0FFD, 0x7D );
ppu.step_pixel(); // 001 304 -> 001 305
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 305 -> 001 306
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 306 -> 001 307
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 307 -> 001 308
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 308 -> 001 309
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 309 -> 001 310
ppu.expect_vram_read( 0x0FF5, 0x75 );
ppu.step_pixel(); // 001 310 -> 001 311
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 311 -> 001 312
ppu.expect_vram_read( 0x0FFD, 0x7D );
ppu.step_pixel(); // 001 312 -> 001 313
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 313 -> 001 314
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 314 -> 001 315
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 315 -> 001 316
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 001 316 -> 001 317
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 317 -> 001 318
ppu.expect_vram_read( 0x0FF5, 0x75 );
ppu.step_pixel(); // 001 318 -> 001 319
ppu.expect_no_vram_read();
ppu.step_pixel(); // 001 319 -> 001 320
ppu.expect_vram_read( 0x0FFD, 0x7D );
ppu.step_pixel(); // 001 320 -> 001 321
ppu.step_scanline();
for _ in 0..257u32 {
ppu.step_pixel();
} // 002 256 -> 002 257
ppu.write_secondary_sprite_ram( 0, 0xFF );
ppu.write_secondary_sprite_ram( 1, 0xFF );
ppu.write_secondary_sprite_ram( 2, 0xFF );
ppu.write_secondary_sprite_ram( 3, 0xFF );
ppu.write_secondary_sprite_ram( 4, 0xFF );
ppu.write_secondary_sprite_ram( 5, 0xFF );
ppu.write_secondary_sprite_ram( 6, 0xFF );
ppu.write_secondary_sprite_ram( 7, 0xFF );
ppu.write_secondary_sprite_ram( 8, 0xFF );
ppu.write_secondary_sprite_ram( 9, 0xFF );
ppu.write_secondary_sprite_ram( 10, 0xFF );
ppu.write_secondary_sprite_ram( 11, 0xFF );
ppu.write_secondary_sprite_ram( 12, 0xFF );
ppu.write_secondary_sprite_ram( 13, 0xFF );
ppu.write_secondary_sprite_ram( 14, 0xFF );
ppu.write_secondary_sprite_ram( 15, 0xFF );
ppu.write_secondary_sprite_ram( 16, 0xFF );
ppu.write_secondary_sprite_ram( 17, 0xFF );
ppu.write_secondary_sprite_ram( 18, 0xFF );
ppu.write_secondary_sprite_ram( 19, 0xFF );
ppu.write_secondary_sprite_ram( 20, 0xFF );
ppu.write_secondary_sprite_ram( 21, 0xFF );
ppu.write_secondary_sprite_ram( 22, 0xFF );
ppu.write_secondary_sprite_ram( 23, 0xFF );
ppu.write_secondary_sprite_ram( 24, 0xFF );
ppu.write_secondary_sprite_ram( 25, 0xFF );
ppu.write_secondary_sprite_ram( 26, 0xFF );
ppu.write_secondary_sprite_ram( 27, 0xFF );
ppu.write_secondary_sprite_ram( 28, 0xFF );
ppu.write_secondary_sprite_ram( 29, 0xFF );
ppu.write_secondary_sprite_ram( 30, 0xFF );
ppu.write_secondary_sprite_ram( 31, 0xFF );
ppu.write_secondary_sprite_ram( 0, 0x00 );
ppu.write_secondary_sprite_ram( 1, 0xAA );
ppu.write_secondary_sprite_ram( 2, 0x00 );
ppu.write_secondary_sprite_ram( 3, 0x00 );
ppu.write_secondary_sprite_ram( 4, 0x00 );
ppu.write_secondary_sprite_ram( 5, 0xBA );
ppu.write_secondary_sprite_ram( 6, 0x40 );
ppu.write_secondary_sprite_ram( 7, 0x08 );
ppu.write_secondary_sprite_ram( 8, 0x00 );
ppu.write_secondary_sprite_ram( 9, 0xCA );
ppu.write_secondary_sprite_ram( 10, 0x80 );
ppu.write_secondary_sprite_ram( 11, 0x10 );
ppu.write_secondary_sprite_ram( 12, 0x00 );
ppu.write_secondary_sprite_ram( 13, 0xDA );
ppu.write_secondary_sprite_ram( 14, 0xC0 );
ppu.write_secondary_sprite_ram( 15, 0x18 );
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 257 -> 002 258
ppu.expect_vram_read( 0x2402, 0x82 );
ppu.step_pixel(); // 002 258 -> 002 259
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 259 -> 002 260
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 260 -> 002 261
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 261 -> 002 262
ppu.expect_vram_read( 0x0AA2, 0x22 );
ppu.step_pixel(); // 002 262 -> 002 263
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 263 -> 002 264
ppu.expect_vram_read( 0x0AAA, 0x2A );
ppu.step_pixel(); // 002 264 -> 002 265
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 265 -> 002 266
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 266 -> 002 267
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 267 -> 002 268
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 268 -> 002 269
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 269 -> 002 270
ppu.expect_vram_read( 0x0BA2, 0x22 );
ppu.step_pixel(); // 002 270 -> 002 271
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 271 -> 002 272
ppu.expect_vram_read( 0x0BAA, 0x2A );
ppu.step_pixel(); // 002 272 -> 002 273
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 273 -> 002 274
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 274 -> 002 275
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 275 -> 002 276
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 276 -> 002 277
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 277 -> 002 278
ppu.expect_vram_read( 0x0CA5, 0x25 );
ppu.step_pixel(); // 002 278 -> 002 279
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 279 -> 002 280
ppu.expect_vram_read( 0x0CAD, 0x2D );
ppu.step_pixel(); // 002 280 -> 002 281
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 281 -> 002 282
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 282 -> 002 283
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 283 -> 002 284
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 284 -> 002 285
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 285 -> 002 286
ppu.expect_vram_read( 0x0DA5, 0x25 );
ppu.step_pixel(); // 002 286 -> 002 287
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 287 -> 002 288
ppu.expect_vram_read( 0x0DAD, 0x2D );
ppu.step_pixel(); // 002 288 -> 002 289
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 289 -> 002 290
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 290 -> 002 291
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 291 -> 002 292
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 292 -> 002 293
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 293 -> 002 294
ppu.expect_vram_read( 0x0FF4, 0x74 );
ppu.step_pixel(); // 002 294 -> 002 295
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 295 -> 002 296
ppu.expect_vram_read( 0x0FFC, 0x7C );
ppu.step_pixel(); // 002 296 -> 002 297
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 297 -> 002 298
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 298 -> 002 299
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 299 -> 002 300
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 300 -> 002 301
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 301 -> 002 302
ppu.expect_vram_read( 0x0FF4, 0x74 );
ppu.step_pixel(); // 002 302 -> 002 303
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 303 -> 002 304
ppu.expect_vram_read( 0x0FFC, 0x7C );
ppu.step_pixel(); // 002 304 -> 002 305
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 305 -> 002 306
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 306 -> 002 307
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 307 -> 002 308
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 308 -> 002 309
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 309 -> 002 310
ppu.expect_vram_read( 0x0FF4, 0x74 );
ppu.step_pixel(); // 002 310 -> 002 311
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 311 -> 002 312
ppu.expect_vram_read( 0x0FFC, 0x7C );
ppu.step_pixel(); // 002 312 -> 002 313
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 313 -> 002 314
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 314 -> 002 315
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 315 -> 002 316
ppu.expect_vram_read( 0x2000, 0x80 );
ppu.step_pixel(); // 002 316 -> 002 317
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 317 -> 002 318
ppu.expect_vram_read( 0x0FF4, 0x74 );
ppu.step_pixel(); // 002 318 -> 002 319
ppu.expect_no_vram_read();
ppu.step_pixel(); // 002 319 -> 002 320
ppu.expect_vram_read( 0x0FFC, 0x7C );
ppu.step_pixel(); // 002 320 -> 002 321
ppu.step_scanline();
assert_eq!( ppu.scanline(), 3 );
assert_eq!( ppu.dot(), 0 );
}

View file

@ -0,0 +1,358 @@
// This file was AUTOGENERATED; do not edit!
#[allow(unused_imports)]
use super::super::assert_eq;
use TestPPU;
#[inline(never)]
pub fn test_vram_access_sprite_rendering_out_of_range( ppu: &mut TestPPU ) {
assert_eq!( ppu.scanline(), 261 );
assert_eq!( ppu.dot(), 0 );
for i in 0..4096u32 {
ppu.write_vram( i as u16, (i + 0x80) as u8 );
}
for i in 0..960u32 {
ppu.write_vram( (0x2000 + i) as u16, (i + 0x80) as u8 );
}
for i in 0..64u32 {
ppu.write_vram( (0x2000 + 960 + i) as u16, (0x80 | i) as u8 );
}
ppu.write_ioreg( 1, 0x14 );
ppu.step_pixel(); // 261 000 -> 261 001
ppu.step_pixel(); // 261 001 -> 261 002
ppu.step_pixel(); // 261 002 -> 261 003
ppu.step_scanline();
for _ in 0..7u32 {
ppu.step_scanline();
} // 006 340 -> 007 000
for _ in 0..257u32 {
ppu.step_pixel();
} // 007 256 -> 007 257
ppu.write_secondary_sprite_ram( 0, 0x00 );
ppu.write_secondary_sprite_ram( 1, 0x77 );
ppu.write_secondary_sprite_ram( 2, 0x00 );
ppu.write_secondary_sprite_ram( 3, 0x00 );
ppu.write_secondary_sprite_ram( 4, 0x01 );
ppu.write_secondary_sprite_ram( 5, 0x88 );
ppu.write_secondary_sprite_ram( 6, 0x00 );
ppu.write_secondary_sprite_ram( 7, 0x00 );
ppu.write_secondary_sprite_ram( 8, 0x07 );
ppu.write_secondary_sprite_ram( 9, 0x99 );
ppu.write_secondary_sprite_ram( 10, 0x00 );
ppu.write_secondary_sprite_ram( 11, 0x00 );
ppu.write_secondary_sprite_ram( 12, 0x08 );
ppu.write_secondary_sprite_ram( 13, 0xAA );
ppu.write_secondary_sprite_ram( 14, 0x00 );
ppu.write_secondary_sprite_ram( 15, 0x00 );
ppu.write_secondary_sprite_ram( 16, 0x09 );
ppu.write_secondary_sprite_ram( 17, 0xBB );
ppu.write_secondary_sprite_ram( 18, 0x00 );
ppu.write_secondary_sprite_ram( 19, 0x00 );
ppu.write_secondary_sprite_ram( 20, 0x0F );
ppu.write_secondary_sprite_ram( 21, 0xCC );
ppu.write_secondary_sprite_ram( 22, 0x00 );
ppu.write_secondary_sprite_ram( 23, 0x00 );
ppu.write_secondary_sprite_ram( 24, 0x10 );
ppu.write_secondary_sprite_ram( 25, 0xDD );
ppu.write_secondary_sprite_ram( 26, 0x00 );
ppu.write_secondary_sprite_ram( 27, 0x00 );
ppu.write_secondary_sprite_ram( 28, 0xFF );
ppu.write_secondary_sprite_ram( 29, 0xEE );
ppu.write_secondary_sprite_ram( 30, 0x00 );
ppu.write_secondary_sprite_ram( 31, 0x00 );
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 257 -> 007 258
ppu.expect_vram_read( 0x2422, 0xA2 );
ppu.step_pixel(); // 007 258 -> 007 259
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 259 -> 007 260
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 260 -> 007 261
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 261 -> 007 262
ppu.expect_vram_read( 0x0777, 0xF7 );
ppu.step_pixel(); // 007 262 -> 007 263
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 263 -> 007 264
ppu.expect_vram_read( 0x077F, 0xFF );
ppu.step_pixel(); // 007 264 -> 007 265
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 265 -> 007 266
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 266 -> 007 267
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 267 -> 007 268
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 268 -> 007 269
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 269 -> 007 270
ppu.expect_vram_read( 0x0886, 0x06 );
ppu.step_pixel(); // 007 270 -> 007 271
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 271 -> 007 272
ppu.expect_vram_read( 0x088E, 0x0E );
ppu.step_pixel(); // 007 272 -> 007 273
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 273 -> 007 274
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 274 -> 007 275
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 275 -> 007 276
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 276 -> 007 277
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 277 -> 007 278
ppu.expect_vram_read( 0x0990, 0x10 );
ppu.step_pixel(); // 007 278 -> 007 279
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 279 -> 007 280
ppu.expect_vram_read( 0x0998, 0x18 );
ppu.step_pixel(); // 007 280 -> 007 281
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 281 -> 007 282
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 282 -> 007 283
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 283 -> 007 284
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 284 -> 007 285
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 285 -> 007 286
ppu.expect_vram_read( 0x0AA7, 0x27 );
ppu.step_pixel(); // 007 286 -> 007 287
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 287 -> 007 288
ppu.expect_vram_read( 0x0AAF, 0x2F );
ppu.step_pixel(); // 007 288 -> 007 289
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 289 -> 007 290
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 290 -> 007 291
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 291 -> 007 292
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 292 -> 007 293
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 293 -> 007 294
ppu.expect_vram_read( 0x0BB6, 0x36 );
ppu.step_pixel(); // 007 294 -> 007 295
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 295 -> 007 296
ppu.expect_vram_read( 0x0BBE, 0x3E );
ppu.step_pixel(); // 007 296 -> 007 297
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 297 -> 007 298
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 298 -> 007 299
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 299 -> 007 300
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 300 -> 007 301
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 301 -> 007 302
ppu.expect_vram_read( 0x0CC0, 0x40 );
ppu.step_pixel(); // 007 302 -> 007 303
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 303 -> 007 304
ppu.expect_vram_read( 0x0CC8, 0x48 );
ppu.step_pixel(); // 007 304 -> 007 305
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 305 -> 007 306
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 306 -> 007 307
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 307 -> 007 308
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 308 -> 007 309
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 309 -> 007 310
ppu.expect_vram_read( 0x0DD7, 0x57 );
ppu.step_pixel(); // 007 310 -> 007 311
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 311 -> 007 312
ppu.expect_vram_read( 0x0DDF, 0x5F );
ppu.step_pixel(); // 007 312 -> 007 313
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 313 -> 007 314
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 314 -> 007 315
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 315 -> 007 316
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 007 316 -> 007 317
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 317 -> 007 318
ppu.expect_vram_read( 0x0EE0, 0x60 );
ppu.step_pixel(); // 007 318 -> 007 319
ppu.expect_no_vram_read();
ppu.step_pixel(); // 007 319 -> 007 320
ppu.expect_vram_read( 0x0EE8, 0x68 );
ppu.step_pixel(); // 007 320 -> 007 321
ppu.step_scanline();
for _ in 0..257u32 {
ppu.step_pixel();
} // 008 256 -> 008 257
ppu.write_secondary_sprite_ram( 0, 0x00 );
ppu.write_secondary_sprite_ram( 1, 0x77 );
ppu.write_secondary_sprite_ram( 2, 0x00 );
ppu.write_secondary_sprite_ram( 3, 0x00 );
ppu.write_secondary_sprite_ram( 4, 0x01 );
ppu.write_secondary_sprite_ram( 5, 0x88 );
ppu.write_secondary_sprite_ram( 6, 0x00 );
ppu.write_secondary_sprite_ram( 7, 0x00 );
ppu.write_secondary_sprite_ram( 8, 0x07 );
ppu.write_secondary_sprite_ram( 9, 0x99 );
ppu.write_secondary_sprite_ram( 10, 0x00 );
ppu.write_secondary_sprite_ram( 11, 0x00 );
ppu.write_secondary_sprite_ram( 12, 0x08 );
ppu.write_secondary_sprite_ram( 13, 0xAA );
ppu.write_secondary_sprite_ram( 14, 0x00 );
ppu.write_secondary_sprite_ram( 15, 0x00 );
ppu.write_secondary_sprite_ram( 16, 0x09 );
ppu.write_secondary_sprite_ram( 17, 0xBB );
ppu.write_secondary_sprite_ram( 18, 0x00 );
ppu.write_secondary_sprite_ram( 19, 0x00 );
ppu.write_secondary_sprite_ram( 20, 0x0F );
ppu.write_secondary_sprite_ram( 21, 0xCC );
ppu.write_secondary_sprite_ram( 22, 0x00 );
ppu.write_secondary_sprite_ram( 23, 0x00 );
ppu.write_secondary_sprite_ram( 24, 0x10 );
ppu.write_secondary_sprite_ram( 25, 0xDD );
ppu.write_secondary_sprite_ram( 26, 0x00 );
ppu.write_secondary_sprite_ram( 27, 0x00 );
ppu.write_secondary_sprite_ram( 28, 0xFF );
ppu.write_secondary_sprite_ram( 29, 0xEE );
ppu.write_secondary_sprite_ram( 30, 0x00 );
ppu.write_secondary_sprite_ram( 31, 0x00 );
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 257 -> 008 258
ppu.expect_vram_read( 0x2422, 0xA2 );
ppu.step_pixel(); // 008 258 -> 008 259
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 259 -> 008 260
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 260 -> 008 261
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 261 -> 008 262
ppu.expect_vram_read( 0x0770, 0xF0 );
ppu.step_pixel(); // 008 262 -> 008 263
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 263 -> 008 264
ppu.expect_vram_read( 0x0778, 0xF8 );
ppu.step_pixel(); // 008 264 -> 008 265
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 265 -> 008 266
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 266 -> 008 267
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 267 -> 008 268
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 268 -> 008 269
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 269 -> 008 270
ppu.expect_vram_read( 0x0887, 0x07 );
ppu.step_pixel(); // 008 270 -> 008 271
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 271 -> 008 272
ppu.expect_vram_read( 0x088F, 0x0F );
ppu.step_pixel(); // 008 272 -> 008 273
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 273 -> 008 274
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 274 -> 008 275
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 275 -> 008 276
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 276 -> 008 277
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 277 -> 008 278
ppu.expect_vram_read( 0x0991, 0x11 );
ppu.step_pixel(); // 008 278 -> 008 279
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 279 -> 008 280
ppu.expect_vram_read( 0x0999, 0x19 );
ppu.step_pixel(); // 008 280 -> 008 281
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 281 -> 008 282
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 282 -> 008 283
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 283 -> 008 284
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 284 -> 008 285
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 285 -> 008 286
ppu.expect_vram_read( 0x0AA0, 0x20 );
ppu.step_pixel(); // 008 286 -> 008 287
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 287 -> 008 288
ppu.expect_vram_read( 0x0AA8, 0x28 );
ppu.step_pixel(); // 008 288 -> 008 289
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 289 -> 008 290
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 290 -> 008 291
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 291 -> 008 292
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 292 -> 008 293
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 293 -> 008 294
ppu.expect_vram_read( 0x0BB7, 0x37 );
ppu.step_pixel(); // 008 294 -> 008 295
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 295 -> 008 296
ppu.expect_vram_read( 0x0BBF, 0x3F );
ppu.step_pixel(); // 008 296 -> 008 297
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 297 -> 008 298
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 298 -> 008 299
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 299 -> 008 300
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 300 -> 008 301
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 301 -> 008 302
ppu.expect_vram_read( 0x0CC1, 0x41 );
ppu.step_pixel(); // 008 302 -> 008 303
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 303 -> 008 304
ppu.expect_vram_read( 0x0CC9, 0x49 );
ppu.step_pixel(); // 008 304 -> 008 305
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 305 -> 008 306
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 306 -> 008 307
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 307 -> 008 308
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 308 -> 008 309
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 309 -> 008 310
ppu.expect_vram_read( 0x0DD0, 0x50 );
ppu.step_pixel(); // 008 310 -> 008 311
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 311 -> 008 312
ppu.expect_vram_read( 0x0DD8, 0x58 );
ppu.step_pixel(); // 008 312 -> 008 313
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 313 -> 008 314
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 314 -> 008 315
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 315 -> 008 316
ppu.expect_vram_read( 0x2020, 0xA0 );
ppu.step_pixel(); // 008 316 -> 008 317
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 317 -> 008 318
ppu.expect_vram_read( 0x0EE1, 0x61 );
ppu.step_pixel(); // 008 318 -> 008 319
ppu.expect_no_vram_read();
ppu.step_pixel(); // 008 319 -> 008 320
ppu.expect_vram_read( 0x0EE9, 0x69 );
ppu.step_pixel(); // 008 320 -> 008 321
ppu.step_scanline();
assert_eq!( ppu.scanline(), 9 );
assert_eq!( ppu.dot(), 0 );
}