Change NT and APU logic so 4-screen games work

This commit is contained in:
Henry Sloan 2021-03-31 14:57:37 -04:00
parent 6512bf1315
commit 27cadf6f5f
2 changed files with 15 additions and 9 deletions

View file

@ -24,6 +24,7 @@ pub struct APU {
frame_counter_cycle: u64,
frame_sequence_len: u8,
frame_sequence_step: u8,
bus_latch: u8,
irq_disable: bool,
frame_irq: bool,
@ -48,6 +49,7 @@ impl APU {
frame_counter_cycle: 0,
frame_sequence_len: 4,
frame_sequence_step: 0,
bus_latch: 0,
irq_disable: false,
frame_irq: false,
@ -89,6 +91,7 @@ impl APU {
self.frame_counter_cycle = 0;
self.frame_sequence_len = 4;
self.frame_sequence_step = 0;
self.bus_latch = 0;
self.dmc.irq = false;
self.irq_disable = false;
@ -166,15 +169,20 @@ impl APU {
// https://wiki.nesdev.com/w/index.php/APU_registers
impl Memory for APU {
fn read(&mut self, addr: u16) -> u8 {
assert!(addr == 0x4015);
if addr != 0x4015 {
return 0;
}
let data = self.peek(addr);
self.frame_irq = false;
self.bus_latch = data;
data
}
fn peek(&self, addr: u16) -> u8 {
assert!(addr == 0x4015);
if addr != 0x4015 {
return 0;
}
((self.dmc.irq as u8) << 7)
| ((self.frame_irq as u8) << 6)
@ -188,6 +196,7 @@ impl Memory for APU {
fn write(&mut self, addr: u16, data: u8) {
assert!((0x4000 <= addr && addr <= 0x4017) && addr != 0x4014);
self.bus_latch = data;
if 0x4000 <= addr && addr <= 0x4003 {
self.pulse1.update_register(addr - 0x4000, data);
} else if 0x4004 <= addr && addr <= 0x4007 {

View file

@ -10,11 +10,12 @@ pub struct NametableMemory {
memory: RAM,
}
// TODO: I think FourScreen should generally map in part or entirely to cartridge memory
impl NametableMemory {
pub fn new(cart: Rc<RefCell<Cartridge>>) -> Self {
Self {
cart,
memory: RAM::new(0x400 * 4, 0x0000),
memory: RAM::new(0x400 * 8, 0x0000),
}
}
@ -24,19 +25,15 @@ impl NametableMemory {
if _addr >= 0x3000 {
_addr -= 0x1000;
}
let mut fix_4s = 0;
let nt_mirroring = match self.cart.borrow().get_nametable_mirroring() {
Mirroring::Vertical => [0, 1, 0, 1],
Mirroring::Horizontal => [0, 0, 1, 1],
Mirroring::FourScreen => {
fix_4s = 0x2000;
[0, 1, 2, 3]
}
Mirroring::FourScreen => [0, 1, 2, 3],
Mirroring::SingleScreenUpper => [1, 1, 1, 1],
Mirroring::SingleScreenLower => [0, 0, 0, 0],
};
nt_mirroring[((_addr - 0x2000) / 0x400) as usize] * 0x400 + (_addr % 0x400) + fix_4s
nt_mirroring[((_addr - 0x2000) / 0x400) as usize] * 0x400 + (_addr % 0x400)
}
}