From ea752bc4c228251b8c3d32a47a7d86cb02fd7f37 Mon Sep 17 00:00:00 2001 From: Theron Spiegl Date: Sat, 25 Jan 2020 15:40:52 -0600 Subject: [PATCH] this has kirby looking mostly normal. bar still shakes when scrolling vertically and is off by a few pixels normally, but much improved. smb3 is still bad, worse once level starts. --- src/cartridge/mmc3.rs | 14 +++++++++++++- src/ppu/cpu_registers.rs | 1 + src/ppu/mod.rs | 35 ++++++++++++++++++++--------------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/cartridge/mmc3.rs b/src/cartridge/mmc3.rs index beefc77..c975a50 100644 --- a/src/cartridge/mmc3.rs +++ b/src/cartridge/mmc3.rs @@ -11,6 +11,7 @@ pub struct Mmc3 { irq_counter: u8, irq_enable: bool, trigger_irq: bool, // signal to send to CPU + reload_counter: bool, prg_ram_bank: Vec, // CPU $6000-$7FFF // 0: $8000-$9FFF swappable, $C000-$DFFF fixed to second-last bank @@ -35,6 +36,7 @@ impl Mmc3 { irq_counter: 0, irq_enable: false, trigger_irq: false, + reload_counter: false, prg_ram_bank: vec![0; 0x2000], prg_rom_bank_mode: false, chr_rom_bank_mode: false, @@ -163,7 +165,7 @@ impl Mapper for Mmc3 { 0x6000..=0x7FFF => self.prg_ram_bank[address % 0x2000] = value, // PRG-RAM 0x8000..=0x9FFF => self.bank_data(value), 0xA000..=0xBFFF => self.prg_ram_protect(), - 0xC000..=0xDFFF => self.irq_counter = 0, // Writing any value to this register reloads the MMC3 IRQ counter at the NEXT rising edge of the PPU address, presumably at PPU cycle 260 of the current scanline. + 0xC000..=0xDFFF => self.reload_counter = true, // Writing any value to this register reloads the MMC3 IRQ counter at the NEXT rising edge of the PPU address, presumably at PPU cycle 260 of the current scanline. 0xE000..=0xFFFF => self.irq_enable = true, _ => println!("bad address written to MMC3: 0x{:X}", address), } @@ -183,8 +185,18 @@ impl Mapper for Mmc3 { fn save_battery_backed_ram(&self) {} fn clock(&mut self) { + if self.reload_counter { + self.irq_counter = self.irq_latch; + self.reload_counter = false; + } + // "Should reload and set IRQ every clock when reload is 0." + if self.irq_latch == 0 && self.irq_enable { + self.irq_counter = self.irq_latch; + self.trigger_irq = true; + } if self.irq_counter == 0 { self.irq_counter = self.irq_latch; + return; } else { self.irq_counter -= 1; } diff --git a/src/ppu/cpu_registers.rs b/src/ppu/cpu_registers.rs index 5be045a..27cacf0 100644 --- a/src/ppu/cpu_registers.rs +++ b/src/ppu/cpu_registers.rs @@ -99,6 +99,7 @@ impl super::Ppu { // cpu writes to 0x2006, PPUADDR pub fn write_address(&mut self, val: u8) { + self.mapper.borrow_mut().clock(); let d = val as u16; match self.w { // first write 0 => { diff --git a/src/ppu/mod.rs b/src/ppu/mod.rs index 5d6e569..b9af746 100644 --- a/src/ppu/mod.rs +++ b/src/ppu/mod.rs @@ -243,21 +243,26 @@ impl Ppu { } // deal with mapper MMC3 - if self.rendering() && ( - self.line_cycle == 260 - && self.sprite_size == 8 - && self.background_pattern_table_base == 0x0000 - && self.sprite_pattern_table_base == 0x1000 - ) || ( - self.line_cycle == 324 - && self.sprite_size == 8 - && self.background_pattern_table_base == 0x1000 - && self.sprite_pattern_table_base == 0x0000 - ) || ( - self.line_cycle == 260 - && self.sprite_size == 16 - // TODO: figure out exact conditions here - ) + // if self.rendering() + // && (1..241).contains(&self.scanline) + // && ( + // ( + // self.line_cycle == 260 + // && self.sprite_size == 8 + // && self.background_pattern_table_base == 0x0000 + // && self.sprite_pattern_table_base == 0x1000 + // ) || ( + // self.line_cycle == 324 + // && self.sprite_size == 8 + // && self.background_pattern_table_base == 0x1000 + // && self.sprite_pattern_table_base == 0x0000 + // ) || ( + // self.line_cycle == 260 + // && self.sprite_size == 16 + // // TODO: figure out exact conditions here + // ) + // ) + if self.rendering() && self.line_cycle == 260 && (1..241).contains(&self.scanline) { self.mapper.borrow_mut().clock() }