Skip to content

Commit

Permalink
wip: dmc
Browse files Browse the repository at this point in the history
  • Loading branch information
luckasRanarison committed Oct 7, 2024
1 parent f8d5dce commit cb5b15b
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 5 deletions.
70 changes: 70 additions & 0 deletions src/apu/channels/dmc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use crate::{
apu::frame_counter::{ClockFrame, Frame},
utils::{BitFlag, Clock},
};

use super::common::{Channel, Timer};

const RATES: [u16; 16] = [
428, 380, 340, 320, 286, 254, 226, 214, 190, 160, 142, 128, 106, 84, 72, 54,
];

#[derive(Debug, Default)]
pub struct Dmc {
irq_flag: bool,
loop_flag: bool,
output_level: u8,
sample_rate: u16,
sample_address: u16,
sample_length: u16,
sample_buffer: Option<u8>,
remaining_bytes: u16,
timer: Timer,
}

impl Dmc {
pub fn irq(&self) -> bool {
self.irq_flag
}
}

impl Channel for Dmc {
fn write_register(&mut self, address: u16, value: u8) {
match address % 4 {
0 => {
self.irq_flag = value.contains(7);
self.loop_flag = value.contains(6);
self.sample_rate = RATES[value.get_range(0..4) as usize];
}
1 => self.output_level = value.get_range(0..7),
2 => self.sample_address = 0xC00 + (64 * value as u16),
_ => self.sample_length = (16 * value as u16) + 1,
}
}

fn raw_sample(&self) -> u8 {
todo!()
}

fn is_active(&self) -> bool {
self.remaining_bytes > 0
}

fn is_mute(&self) -> bool {
todo!()
}

fn set_enabled(&mut self, value: bool) {
todo!()
}
}

impl Clock for Dmc {
fn tick(&mut self) {}
}

impl ClockFrame for Dmc {
fn tick_frame(&mut self, frame: &Frame) {
todo!()
}
}
2 changes: 2 additions & 0 deletions src/apu/channels/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
mod common;
mod dmc;
mod noise;
mod pulse;
mod triangle;

pub use common::Channel;
pub use dmc::Dmc;
pub use noise::Noise;
pub use pulse::Pulse;
pub use triangle::Triangle;
17 changes: 13 additions & 4 deletions src/apu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
mod channels;
mod frame_counter;

use channels::{Channel, Noise, Pulse, Triangle};
use channels::{Channel, Dmc, Noise, Pulse, Triangle};
use frame_counter::{ClockFrame, FrameCounter};

use crate::{
Expand All @@ -17,9 +17,9 @@ mod status_flag {
pub const P2: u8 = 1;
pub const T : u8 = 2;
pub const N : u8 = 3;
//pub const D : u8 = 4;
pub const D : u8 = 4;
pub const F : u8 = 6;
//pub const I : u8 = 7;
pub const I : u8 = 7;
}

#[derive(Debug, Default)]
Expand All @@ -28,6 +28,7 @@ pub struct Apu {
pulse2: Pulse,
triangle: Triangle,
noise: Noise,
dmc: Dmc,
frame_counter: FrameCounter,
cycle: u64,
buffer: Vec<f32>,
Expand All @@ -49,7 +50,9 @@ impl Apu {
| (self.pulse2.is_active() as u8) << status_flag::P2
| (self.triangle.is_active() as u8) << status_flag::T
| (self.noise.is_active() as u8) << status_flag::N
| (self.frame_counter.irq() as u8) << status_flag::F;
| (self.dmc.is_active() as u8) << status_flag::D
| (self.frame_counter.irq() as u8) << status_flag::F
| (self.dmc.irq() as u8) << status_flag::I;

self.frame_counter.clear_interrupt();

Expand All @@ -72,11 +75,16 @@ impl Apu {
self.noise.write_register(address, value);
}

pub fn write_dmc(&mut self, address: u16, value: u8) {
self.dmc.write_register(address, value);
}

pub fn write_status(&mut self, value: u8) {
self.pulse1.set_enabled(value.contains(status_flag::P1));
self.pulse2.set_enabled(value.contains(status_flag::P2));
self.triangle.set_enabled(value.contains(status_flag::T));
self.noise.set_enabled(value.contains(status_flag::N));
self.dmc.set_enabled(value.contains(status_flag::D));
}

pub fn write_frame_counter(&mut self, value: u8) {
Expand Down Expand Up @@ -126,6 +134,7 @@ impl Clock for Apu {
self.noise.tick_frame(&frame);
}

// FIXME: find a better sampling strategy
// 44_100 / 60 == 735 samples/frame
// 29970 (CPU cycle) / 735 == 40 cycles/frame
if self.cycle % 40 == 0 {
Expand Down
2 changes: 1 addition & 1 deletion src/bus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl Bus for MainBus {
0x4004..=0x4007 => self.apu.borrow_mut().write_pulse2(address, value),
0x4008..=0x400B => self.apu.borrow_mut().write_triangle(address, value),
0x400C..=0x400F => self.apu.borrow_mut().write_noise(address, value),
0x4010..=0x4013 => {} // TODO: DMC
0x4010..=0x4013 => self.apu.borrow_mut().write_dmc(address, value),
0x4015 => self.apu.borrow_mut().write_status(value),
0x4017 => self.apu.borrow_mut().write_frame_counter(value),
0x4014 => self.setup_oam_dma(value),
Expand Down

0 comments on commit cb5b15b

Please sign in to comment.