spaces
This commit is contained in:
parent
53b4454f98
commit
e4d8bba720
|
@ -18,22 +18,22 @@ impl DMC {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clock(&mut self) {
|
pub fn clock(&mut self) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_control(&mut self, value: u8) {
|
pub fn write_control(&mut self, value: u8) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn direct_load(&mut self, value: u8) {
|
pub fn direct_load(&mut self, value: u8) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_sample_address(&mut self, value: u8) {
|
pub fn write_sample_address(&mut self, value: u8) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_sample_length(&mut self, value: u8) {
|
pub fn write_sample_length(&mut self, value: u8) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,7 +25,7 @@ pub struct Apu {
|
||||||
triangle: Triangle,
|
triangle: Triangle,
|
||||||
noise: Noise,
|
noise: Noise,
|
||||||
dmc: DMC,
|
dmc: DMC,
|
||||||
|
|
||||||
square_table: Vec<f32>,
|
square_table: Vec<f32>,
|
||||||
tnd_table: Vec<f32>,
|
tnd_table: Vec<f32>,
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ impl Apu {
|
||||||
fn write_frame_counter(&mut self, value: u8) {
|
fn write_frame_counter(&mut self, value: u8) {
|
||||||
// 0 selects 4-step sequence, 1 selects 5-step sequence
|
// 0 selects 4-step sequence, 1 selects 5-step sequence
|
||||||
self.frame_sequence = if value & (1<<7) == 0 { 4 } else { 5 };
|
self.frame_sequence = if value & (1<<7) == 0 { 4 } else { 5 };
|
||||||
// If set, the frame interrupt flag is cleared, otherwise it is unaffected.
|
// If set, the frame interrupt flag is cleared, otherwise it is unaffected.
|
||||||
if value & (1<<6) != 0 {
|
if value & (1<<6) != 0 {
|
||||||
self.interrupt_inhibit = false;
|
self.interrupt_inhibit = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use super::envelope::Envelope;
|
||||||
const NOISE_TABLE: [u16; 16] = [4, 8, 16, 32, 64, 96, 128, 160, 202, 254, 380, 508, 762, 1016, 2034, 4068];
|
const NOISE_TABLE: [u16; 16] = [4, 8, 16, 32, 64, 96, 128, 160, 202, 254, 380, 508, 762, 1016, 2034, 4068];
|
||||||
|
|
||||||
// $400E M---.PPPP Mode and period (write)
|
// $400E M---.PPPP Mode and period (write)
|
||||||
// bit 7 M--- ---- Mode flag
|
// bit 7 M--- ---- Mode flag
|
||||||
pub struct Noise {
|
pub struct Noise {
|
||||||
pub sample: u16, // output value that gets sent to the mixer
|
pub sample: u16, // output value that gets sent to the mixer
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
|
@ -37,7 +37,7 @@ impl Noise {
|
||||||
} else {
|
} else {
|
||||||
self.timer -= 1;
|
self.timer -= 1;
|
||||||
}
|
}
|
||||||
// The mixer receives the current envelope volume except when
|
// The mixer receives the current envelope volume except when
|
||||||
// Bit 0 of the shift register is set, or the length counter is zero
|
// Bit 0 of the shift register is set, or the length counter is zero
|
||||||
self.sample = if self.linear_feedback_sr & 1 == 1 || self.length_counter == 0 {
|
self.sample = if self.linear_feedback_sr & 1 == 1 || self.length_counter == 0 {
|
||||||
0
|
0
|
||||||
|
|
|
@ -100,7 +100,7 @@ impl Square {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whenever the current period changes for any reason, whether by $400x writes or by sweep, the target period also changes.
|
// Whenever the current period changes for any reason, whether by $400x writes or by sweep, the target period also changes.
|
||||||
pub fn calculate_target_period(&mut self) {
|
pub fn calculate_target_period(&mut self) {
|
||||||
// The sweep unit continuously calculates each channel's target period in this way:
|
// The sweep unit continuously calculates each channel's target period in this way:
|
||||||
// A barrel shifter shifts the channel's 11-bit raw timer period right by the shift count, producing the change amount.
|
// A barrel shifter shifts the channel's 11-bit raw timer period right by the shift count, producing the change amount.
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub struct Triangle {
|
||||||
waveform_counter: usize,
|
waveform_counter: usize,
|
||||||
pub length_counter: u8,
|
pub length_counter: u8,
|
||||||
length_counter_halt: bool, // (this bit is also the linear counter's control flag)
|
length_counter_halt: bool, // (this bit is also the linear counter's control flag)
|
||||||
|
|
||||||
linear_counter: u8,
|
linear_counter: u8,
|
||||||
counter_reload_value: u8,
|
counter_reload_value: u8,
|
||||||
linear_counter_reload: bool,
|
linear_counter_reload: bool,
|
||||||
|
@ -37,9 +37,9 @@ impl Triangle {
|
||||||
pub fn clock(&mut self) {
|
pub fn clock(&mut self) {
|
||||||
if self.timer == 0 {
|
if self.timer == 0 {
|
||||||
self.timer = self.timer_period;
|
self.timer = self.timer_period;
|
||||||
// The sequencer is clocked by the timer as long as both the linear counter and the length counter are nonzero.
|
// The sequencer is clocked by the timer as long as both the linear counter and the length counter are nonzero.
|
||||||
if self.linear_counter != 0 && self.length_counter != 0 {
|
if self.linear_counter != 0 && self.length_counter != 0 {
|
||||||
self.waveform_counter = (self.waveform_counter + 1) % 32;
|
self.waveform_counter = (self.waveform_counter + 1) % 32;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.timer -= 1;
|
self.timer -= 1;
|
||||||
|
@ -60,7 +60,7 @@ impl Triangle {
|
||||||
self.linear_counter_reload = false;
|
self.linear_counter_reload = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clock_length_counter(&mut self) {
|
pub fn clock_length_counter(&mut self) {
|
||||||
if !(self.length_counter == 0 || self.length_counter_halt) {
|
if !(self.length_counter == 0 || self.length_counter_halt) {
|
||||||
self.length_counter -= 1;
|
self.length_counter -= 1;
|
||||||
|
|
|
@ -42,8 +42,8 @@ impl AudioCallback for ApuSampler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initialize(sdl_context: &Sdl, buffer: Arc<Mutex<Vec<f32>>>)
|
pub fn initialize(sdl_context: &Sdl, buffer: Arc<Mutex<Vec<f32>>>)
|
||||||
-> Result<sdl2::audio::AudioDevice<ApuSampler>, String>
|
-> Result<sdl2::audio::AudioDevice<ApuSampler>, String>
|
||||||
{
|
{
|
||||||
let audio_subsystem = sdl_context.audio()?;
|
let audio_subsystem = sdl_context.audio()?;
|
||||||
let desired_spec = AudioSpecDesired {
|
let desired_spec = AudioSpecDesired {
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl Mapper for Mmc3 {
|
||||||
},
|
},
|
||||||
|
|
||||||
0x6000..=0x7FFF => self.prg_ram_bank[address % 0x2000], // PRG-RAM
|
0x6000..=0x7FFF => self.prg_ram_bank[address % 0x2000], // PRG-RAM
|
||||||
|
|
||||||
0x8000..=0xFFFF => { // reading from PRG ROM, dealing with 8K banks of 16K chunks
|
0x8000..=0xFFFF => { // reading from PRG ROM, dealing with 8K banks of 16K chunks
|
||||||
let offset_8k = address % 0x2000;
|
let offset_8k = address % 0x2000;
|
||||||
let num_banks = self.cart.prg_rom_size * 2;
|
let num_banks = self.cart.prg_rom_size * 2;
|
||||||
|
@ -118,7 +118,7 @@ impl Mapper for Mmc3 {
|
||||||
0xA000..=0xBFFF => self.bank_registers[7],
|
0xA000..=0xBFFF => self.bank_registers[7],
|
||||||
0xC000..=0xDFFF => self.bank_registers[6],
|
0xC000..=0xDFFF => self.bank_registers[6],
|
||||||
0xE000..=0xFFFF => num_banks - 1,
|
0xE000..=0xFFFF => num_banks - 1,
|
||||||
_ => panic!("oh no"),
|
_ => panic!("oh no"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
false => {
|
false => {
|
||||||
|
@ -134,7 +134,7 @@ impl Mapper for Mmc3 {
|
||||||
let chunk_num = bank_num / 2;
|
let chunk_num = bank_num / 2;
|
||||||
let chunk_half = (bank_num % 2) * 0x2000;
|
let chunk_half = (bank_num % 2) * 0x2000;
|
||||||
self.cart.prg_rom[chunk_num][chunk_half + offset_8k]
|
self.cart.prg_rom[chunk_num][chunk_half + offset_8k]
|
||||||
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
println!("bad address read from MMC3: 0x{:X}", address);
|
println!("bad address read from MMC3: 0x{:X}", address);
|
||||||
|
|
|
@ -67,7 +67,7 @@ impl super::Cpu {
|
||||||
let low_byte = self.read(operand_address) as usize;
|
let low_byte = self.read(operand_address) as usize;
|
||||||
// BUG TIME! from https://wiki.nesdev.com/w/index.php/Errata
|
// BUG TIME! from https://wiki.nesdev.com/w/index.php/Errata
|
||||||
// "JMP ($xxyy), or JMP indirect, does not advance pages if the lower eight bits
|
// "JMP ($xxyy), or JMP indirect, does not advance pages if the lower eight bits
|
||||||
// of the specified address is $FF; the upper eight bits are fetched from $xx00,
|
// of the specified address is $FF; the upper eight bits are fetched from $xx00,
|
||||||
// 255 bytes earlier, instead of the expected following byte."
|
// 255 bytes earlier, instead of the expected following byte."
|
||||||
let high_byte = if operand_address & 0xFF == 0xFF {
|
let high_byte = if operand_address & 0xFF == 0xFF {
|
||||||
(self.read(operand_address as usize - 0xFF) as usize) << 8
|
(self.read(operand_address as usize - 0xFF) as usize) << 8
|
||||||
|
|
|
@ -137,7 +137,7 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step(&mut self) -> u64 {
|
pub fn step(&mut self) -> u64 {
|
||||||
|
|
||||||
// skip cycles from OAM DMA if necessary
|
// skip cycles from OAM DMA if necessary
|
||||||
if self.delay > 0 {
|
if self.delay > 0 {
|
||||||
self.delay -= 1;
|
self.delay -= 1;
|
||||||
|
|
|
@ -164,7 +164,7 @@ impl super::Cpu {
|
||||||
pub fn cli(&mut self, _address: usize, _mode: Mode) {
|
pub fn cli(&mut self, _address: usize, _mode: Mode) {
|
||||||
self.P &= 0xFF - INTERRUPT_DISABLE_FLAG;
|
self.P &= 0xFF - INTERRUPT_DISABLE_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clv(&mut self, _address: usize, _mode: Mode) {
|
pub fn clv(&mut self, _address: usize, _mode: Mode) {
|
||||||
self.P &= 0xFF - OVERFLOW_FLAG;
|
self.P &= 0xFF - OVERFLOW_FLAG;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ impl super::Cpu {
|
||||||
Mode::ZPY => 2,
|
Mode::ZPY => 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_offset_to_pc(&mut self, offset: i8) {
|
pub fn add_offset_to_pc(&mut self, offset: i8) {
|
||||||
match offset >= 0 {
|
match offset >= 0 {
|
||||||
true => {
|
true => {
|
||||||
|
|
|
@ -147,7 +147,8 @@ Failed tests from instr_test-v5/rom_singles/:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1. A12 stuff controls when IRQs
|
1. A12 stuff controls when IRQs fire. Don't think there are serious problems with when IRQs fire anymore,
|
||||||
2. Don't think the timing stuff is related to the palette and background table issues in SMB3
|
though vertical scroll is still shaky in Kirby.
|
||||||
|
2. Don't think the timing stuff is related to the palette and background table issues in SMB2/3.
|
||||||
|
How can the palette be wrong? Or is it not, but the attribute bits are reading wrong?
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
impl super::Ppu {
|
impl super::Ppu {
|
||||||
|
|
||||||
// cpu writes to 0x2000, PPUCTRL
|
// cpu writes to 0x2000, PPUCTRL
|
||||||
pub fn write_controller(&mut self, byte: u8) {
|
pub fn write_controller(&mut self, byte: u8) {
|
||||||
|
|
||||||
|
@ -144,14 +144,14 @@ impl super::Ppu {
|
||||||
As for 0x3F00 through 0x3FFF, the palette RAM indexes and their mirrors, need to find corresponding nametable?
|
As for 0x3F00 through 0x3FFF, the palette RAM indexes and their mirrors, need to find corresponding nametable?
|
||||||
There are 4 nametables, duplicated once, so 8. There is one palette RAM index, mirrored 7 times, so 8.
|
There are 4 nametables, duplicated once, so 8. There is one palette RAM index, mirrored 7 times, so 8.
|
||||||
So to get from the fifth pallete RAM mirror, which would be 0x3F80, you'd select the 5th nametable,
|
So to get from the fifth pallete RAM mirror, which would be 0x3F80, you'd select the 5th nametable,
|
||||||
which would be the first mirrored nametable, 0x3000?
|
which would be the first mirrored nametable, 0x3000?
|
||||||
No, just subtract 0x1000. https://forums.nesdev.com/viewtopic.php?f=3&t=18627:
|
No, just subtract 0x1000. https://forums.nesdev.com/viewtopic.php?f=3&t=18627:
|
||||||
|
|
||||||
"However, I couldn't find any info on exactly which address should be used to populate the read buffer in this scenario.
|
"However, I couldn't find any info on exactly which address should be used to populate the read buffer in this scenario.
|
||||||
From other emulators, it appears to be PPU_ADDR - 0x1000, but I can't really intuit why that is the case."
|
From other emulators, it appears to be PPU_ADDR - 0x1000, but I can't really intuit why that is the case."
|
||||||
|
|
||||||
"It's the case because the majority of the time (that is, on just about every board but GTROM),
|
"It's the case because the majority of the time (that is, on just about every board but GTROM),
|
||||||
video memory $3000-$3FFF mirrors $2000-$2FFF. When PA13 is high ($2000-$3FFF), nothing is listening
|
video memory $3000-$3FFF mirrors $2000-$2FFF. When PA13 is high ($2000-$3FFF), nothing is listening
|
||||||
to PA12 (the line that distinguishes $0000-$0FFF from $1000-$1FFF and distinguishes $2000-$2FFF from $3000-$3FFF)."
|
to PA12 (the line that distinguishes $0000-$0FFF from $1000-$1FFF and distinguishes $2000-$2FFF from $3000-$3FFF)."
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::cartridge::Mirror;
|
use crate::cartridge::Mirror;
|
||||||
|
|
||||||
impl super::Ppu {
|
impl super::Ppu {
|
||||||
|
|
||||||
pub fn read(&mut self, addr: usize) -> u8 {
|
pub fn read(&mut self, addr: usize) -> u8 {
|
||||||
let address = addr % 0x4000;
|
let address = addr % 0x4000;
|
||||||
match addr {
|
match addr {
|
||||||
|
@ -26,7 +26,7 @@ impl super::Ppu {
|
||||||
// Addresses $3F10/$3F14/$3F18/$3F1C are mirrors of $3F00/$3F04/$3F08/$3F0C.
|
// Addresses $3F10/$3F14/$3F18/$3F1C are mirrors of $3F00/$3F04/$3F08/$3F0C.
|
||||||
// Note that this goes for writing as well as reading.
|
// Note that this goes for writing as well as reading.
|
||||||
// A symptom of not having implemented this correctly in an emulator is the sky being black in Super Mario Bros.,
|
// A symptom of not having implemented this correctly in an emulator is the sky being black in Super Mario Bros.,
|
||||||
// which writes the backdrop color through $3F10.
|
// which writes the backdrop color through $3F10.
|
||||||
match address % 0x10 {
|
match address % 0x10 {
|
||||||
0x00 => {
|
0x00 => {
|
||||||
self.palette_ram[0] = value;
|
self.palette_ram[0] = value;
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub struct Ppu {
|
||||||
nametable_C: Vec<u8>,
|
nametable_C: Vec<u8>,
|
||||||
nametable_D: Vec<u8>,
|
nametable_D: Vec<u8>,
|
||||||
|
|
||||||
// The palette shared by both background and sprites.
|
// The palette shared by both background and sprites.
|
||||||
// Consists of 32 bytes, each of which represents an index into the global PALETTE_TABLE.
|
// Consists of 32 bytes, each of which represents an index into the global PALETTE_TABLE.
|
||||||
// The first 16 bytes are for the background, the second half for the sprites.
|
// The first 16 bytes are for the background, the second half for the sprites.
|
||||||
palette_ram: Vec<u8>, // Palette RAM indexes.
|
palette_ram: Vec<u8>, // Palette RAM indexes.
|
||||||
|
@ -197,10 +197,10 @@ impl Ppu {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// During dots 280 to 304 of the pre-render scanline (end of vblank)
|
// During dots 280 to 304 of the pre-render scanline (end of vblank)
|
||||||
// If rendering is enabled, at the end of vblank, shortly after the horizontal bits
|
// If rendering is enabled, at the end of vblank, shortly after the horizontal bits
|
||||||
// are copied from t to v at dot 257, the PPU will repeatedly copy the vertical bits
|
// are copied from t to v at dot 257, the PPU will repeatedly copy the vertical bits
|
||||||
// from t to v from dots 280 to 304, completing the full initialization of v from t:
|
// from t to v from dots 280 to 304, completing the full initialization of v from t:
|
||||||
if rendering && self.scanline == 261 && self.line_cycle >= 280 && self.line_cycle <= 304 {
|
if rendering && self.scanline == 261 && self.line_cycle >= 280 && self.line_cycle <= 304 {
|
||||||
self.copy_vertical();
|
self.copy_vertical();
|
||||||
|
|
|
@ -87,7 +87,7 @@ impl super::Ppu {
|
||||||
let low_palette_bit = (self.background_palette_sr_low & (1 << (7-self.x)) != 0) as u8;
|
let low_palette_bit = (self.background_palette_sr_low & (1 << (7-self.x)) != 0) as u8;
|
||||||
let high_palette_bit = (self.background_palette_sr_high & (1 << (7-self.x)) != 0) as u8;
|
let high_palette_bit = (self.background_palette_sr_high & (1 << (7-self.x)) != 0) as u8;
|
||||||
let palette_offset = (high_palette_bit << 1) | low_palette_bit;
|
let palette_offset = (high_palette_bit << 1) | low_palette_bit;
|
||||||
|
|
||||||
if x < 8 && !self.show_background_left {
|
if x < 8 && !self.show_background_left {
|
||||||
background_pixel = 0;
|
background_pixel = 0;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ impl super::Ppu {
|
||||||
// let pixel = self.read(palette_address as usize) as usize;
|
// let pixel = self.read(palette_address as usize) as usize;
|
||||||
let pixel = self.palette_ram[palette_address as usize] as usize;
|
let pixel = self.palette_ram[palette_address as usize] as usize;
|
||||||
let color: (u8, u8, u8) = super::PALETTE_TABLE[pixel];
|
let color: (u8, u8, u8) = super::PALETTE_TABLE[pixel];
|
||||||
|
|
||||||
(x,y,color)
|
(x,y,color)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ impl super::Ppu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate_sprites(&mut self) {
|
pub fn evaluate_sprites(&mut self) {
|
||||||
let mut sprite_count = 0;
|
let mut sprite_count = 0;
|
||||||
for n in 0..64 {
|
for n in 0..64 {
|
||||||
let y_coord = self.primary_oam[(n*4)+0];
|
let y_coord = self.primary_oam[(n*4)+0];
|
||||||
|
@ -214,7 +214,7 @@ impl super::Ppu {
|
||||||
} else {
|
} else {
|
||||||
self.sprite_size as usize - 1 - (self.scanline - sprite_y_position)
|
self.sprite_size as usize - 1 - (self.scanline - sprite_y_position)
|
||||||
};
|
};
|
||||||
// For 8x16 sprites, the PPU ignores the pattern table selection and selects a pattern table from bit 0 of this number.
|
// For 8x16 sprites, the PPU ignores the pattern table selection and selects a pattern table from bit 0 of this number.
|
||||||
} else {
|
} else {
|
||||||
address = if sprite_tile_index & 1 == 0 { 0x0 } else { 0x1000 };
|
address = if sprite_tile_index & 1 == 0 { 0x0 } else { 0x1000 };
|
||||||
address += (sprite_tile_index & 0xFFFF-1) << 4; // turn off bottom bit BEFORE shifting
|
address += (sprite_tile_index & 0xFFFF-1) << 4; // turn off bottom bit BEFORE shifting
|
||||||
|
@ -264,8 +264,8 @@ impl super::Ppu {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inc_y(&mut self) {
|
pub fn inc_y(&mut self) {
|
||||||
// If rendering is enabled, fine Y is incremented at dot 256 of each scanline,
|
// If rendering is enabled, fine Y is incremented at dot 256 of each scanline,
|
||||||
// overflowing to coarse Y, and finally adjusted to wrap among the nametables vertically.
|
// overflowing to coarse Y, and finally adjusted to wrap among the nametables vertically.
|
||||||
let mut fine_y = (self.v & 0b01110000_00000000) >> 12;
|
let mut fine_y = (self.v & 0b01110000_00000000) >> 12;
|
||||||
let mut coarse_y = (self.v & 0b00000011_11100000) >> 5;
|
let mut coarse_y = (self.v & 0b00000011_11100000) >> 5;
|
||||||
if fine_y < 7 {
|
if fine_y < 7 {
|
||||||
|
@ -273,7 +273,7 @@ impl super::Ppu {
|
||||||
} else {
|
} else {
|
||||||
fine_y = 0;
|
fine_y = 0;
|
||||||
// Row 29 is the last row of tiles in a nametable. To wrap to the next nametable when
|
// Row 29 is the last row of tiles in a nametable. To wrap to the next nametable when
|
||||||
// incrementing coarse Y from 29, the vertical nametable is switched by toggling bit
|
// incrementing coarse Y from 29, the vertical nametable is switched by toggling bit
|
||||||
// 11, and coarse Y wraps to row 0.
|
// 11, and coarse Y wraps to row 0.
|
||||||
if coarse_y == 29 {
|
if coarse_y == 29 {
|
||||||
self.v ^= 1<<11;
|
self.v ^= 1<<11;
|
||||||
|
@ -320,7 +320,7 @@ impl super::Ppu {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn y_in_range(&self, y_coord: u8) -> bool {
|
pub fn y_in_range(&self, y_coord: u8) -> bool {
|
||||||
self.scanline >= (y_coord as usize) &&
|
self.scanline >= (y_coord as usize) &&
|
||||||
self.scanline - (y_coord as usize) < self.sprite_size as usize
|
self.scanline - (y_coord as usize) < self.sprite_size as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue