WIP vblank nmi

This commit is contained in:
2023-07-02 17:30:42 -05:00
parent 300456a2ef
commit 9d99d2d194
4 changed files with 94 additions and 29 deletions

View File

@@ -49,7 +49,7 @@ impl Bus {
0x0000..=0x1FFF => MemoryMap::WRAM,
0x2100..=0x21FF => MemoryMap::PPU,
0x4016..=0x4017 => MemoryMap::Joypad,
0x4200..=0x43FF => MemoryMap::CPU,
0x4200..=0x420F => MemoryMap::CPU,
_ => MemoryMap::Cartridge,
},
_ => MemoryMap::Cartridge,
@@ -61,7 +61,10 @@ impl Bus {
match section {
MemoryMap::WRAM => self.read_wram(address),
MemoryMap::PPU => self.ppu.registers.read(address as u16),
MemoryMap::CPU => self.internal_registers.read(address as u16),
MemoryMap::CPU => self.internal_registers.read(
address as u16,
&self.ppu.registers,
),
MemoryMap::Joypad => 0x00, // TODO: Placeholder
MemoryMap::Cartridge => self.rom.read(address),
}

View File

@@ -1,24 +1,62 @@
use crate::ppu::registers::PPURegisters;
use crate::ppu::registers::{
RDNMI
};
pub const INTERNAL_REGISTERS_ADDRESS: u16 = 0x4200;
pub struct InternalRegisters {
_registers: [u8; 32],
registers: [u8; 32],
}
impl InternalRegisters {
pub fn new() -> Self {
Self {
_registers: [0; 32],
registers: [0; 32],
}
}
pub fn read(&self, _address: u16) -> u8 {
// TODO: Placeholder
// self.registers[(address - INTERNAL_REGISTERS_ADDRESS) as usize]
0x00
fn _read(&self, address: u16) -> u8 {
self.registers[(address - INTERNAL_REGISTERS_ADDRESS) as usize]
}
pub fn write(&mut self, _address: u16, _value: u8) {
// TODO: Placeholder
// self.registers[(address - INTERNAL_REGISTERS_ADDRESS) as usize] = value;
fn _write(&mut self, address: u16, value: u8) {
self.registers[(address - INTERNAL_REGISTERS_ADDRESS) as usize] = value
}
pub fn read(&self, address: u16, ppu_registers: &PPURegisters) -> u8 {
match address {
RDNMI => self.read_vblank_nmi(ppu_registers),
_ => self._read(address),
}
}
pub fn write(&mut self, address: u16, value: u8) {
self._write(address, value);
}
fn read_vblank_nmi(&self, ppu_registers: &PPURegisters) -> u8 {
let byte = self._read(RDNMI);
// TODO: when this register is read, bit 7 is cleared
(byte & 0x7F) | ((ppu_registers.is_vblanking() as u8) << 7)
}
}
#[cfg(test)]
mod ppu_general_test {
use super::*;
#[test]
fn test_read_vblank_nmi() {
let registers = InternalRegisters::new();
let mut ppu_registers = PPURegisters::new();
ppu_registers.h_count = 20;
assert_eq!(registers.read_vblank_nmi(&ppu_registers), 0x00);
ppu_registers.h_count = 300;
assert_eq!(registers.read_vblank_nmi(&ppu_registers), 0x80);
// TODO: reset vblank bit after read
// ppu_registers.h_count = 300;
// assert_eq!(registers.read_vblank_nmi(&ppu_registers), 0x00);
}
}

View File

@@ -2,8 +2,6 @@ use super::registers::PPURegisters;
pub struct PPU {
framebuffer: Vec<u8>,
h_count: u16,
v_count: u16,
pub registers: PPURegisters,
}
@@ -11,8 +9,6 @@ impl PPU {
pub fn new() -> Self {
Self {
framebuffer: vec![],
h_count: 0,
v_count: 0,
registers: PPURegisters::new(),
}
}
@@ -28,12 +24,12 @@ impl PPU {
}
fn increment_hv_count(&mut self) {
self.h_count += 1;
if self.h_count > 339 {
self.h_count = 0;
self.v_count += 1;
if self.v_count > 261 {
self.v_count = 0;
self.registers.h_count += 1;
if self.registers.h_count > 339 {
self.registers.h_count = 0;
self.registers.v_count += 1;
if self.registers.v_count > 261 {
self.registers.v_count = 0;
}
}
}
@@ -52,17 +48,17 @@ mod ppu_general_test {
fn test_increment_hv_count() {
let mut ppu = PPU::new();
ppu.increment_hv_count();
assert_eq!(ppu.h_count, 1);
assert_eq!(ppu.registers.h_count, 1);
ppu.h_count = 339;
ppu.registers.h_count = 339;
ppu.increment_hv_count();
assert_eq!(ppu.h_count, 0);
assert_eq!(ppu.v_count, 1);
assert_eq!(ppu.registers.h_count, 0);
assert_eq!(ppu.registers.v_count, 1);
ppu.h_count = 339;
ppu.v_count = 261;
ppu.registers.h_count = 339;
ppu.registers.v_count = 261;
ppu.increment_hv_count();
assert_eq!(ppu.h_count, 0);
assert_eq!(ppu.v_count, 0);
assert_eq!(ppu.registers.h_count, 0);
assert_eq!(ppu.registers.v_count, 0);
}
}

View File

@@ -114,12 +114,16 @@ pub enum Background {
pub struct PPURegisters {
data: [u8; 256],
pub h_count: u16,
pub v_count: u16,
}
impl PPURegisters {
pub fn new() -> Self {
Self {
data: [0x00; 256],
h_count: 0,
v_count: 0,
}
}
@@ -167,6 +171,13 @@ impl PPURegisters {
_ => unreachable!(),
}
}
pub fn is_vblanking(&self) -> bool {
if self.h_count >= 1 && self.h_count <= 224 {
return false
}
return true
}
}
@@ -189,4 +200,21 @@ mod ppu_registers_test {
registers.write(BG1SC, 2);
assert_eq!(registers.get_bg_size(Background::Bg1), BgSize::T32x64);
}
#[test]
fn test_is_vblanking() {
let mut registers = PPURegisters::new();
registers.h_count = 339;
assert_eq!(registers.is_vblanking(), true);
registers.h_count = 0;
assert_eq!(registers.is_vblanking(), true);
registers.h_count = 225;
assert_eq!(registers.is_vblanking(), true);
registers.h_count = 224;
assert_eq!(registers.is_vblanking(), false);
registers.h_count = 2;
assert_eq!(registers.is_vblanking(), false);
registers.h_count = 50;
assert_eq!(registers.is_vblanking(), false);
}
}