Major refactor
- CPU is now it's own module - Memory object is now shared to support mapper chips - ROM is now stored as `Arc<[u8]>` to support mapper chips
This commit is contained in:
58
src/apu.rs
58
src/apu.rs
@@ -1,6 +1,7 @@
|
||||
use tracing::debug;
|
||||
|
||||
bitfield::bitfield! {
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DutyVol(u8);
|
||||
impl Debug;
|
||||
duty, set_duty: 7, 6;
|
||||
@@ -10,6 +11,7 @@ bitfield::bitfield! {
|
||||
}
|
||||
|
||||
bitfield::bitfield! {
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Sweep(u8);
|
||||
impl Debug;
|
||||
enable, set_enable: 7;
|
||||
@@ -19,12 +21,14 @@ bitfield::bitfield! {
|
||||
}
|
||||
|
||||
bitfield::bitfield! {
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub struct LengthTimerHigh(u8);
|
||||
impl Debug;
|
||||
length, set_length: 7, 3;
|
||||
timer_high, set_timer_high: 2, 0;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct PulseChannel {
|
||||
enabled: bool,
|
||||
duty_vol: DutyVol,
|
||||
@@ -92,12 +96,15 @@ bitfield::bitfield! {
|
||||
value, set_value: 6, 0;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct TriangleChannel {
|
||||
enabled: bool,
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
struct NoiseChannel {
|
||||
enabled: bool,
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
struct DeltaChannel {
|
||||
enabled: bool,
|
||||
}
|
||||
@@ -108,6 +115,7 @@ impl DeltaChannel {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct FrameCounter {
|
||||
count: usize,
|
||||
mode_5_step: bool,
|
||||
@@ -115,6 +123,7 @@ struct FrameCounter {
|
||||
irq: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct APU {
|
||||
pulse_1: PulseChannel,
|
||||
pulse_2: PulseChannel,
|
||||
@@ -185,6 +194,14 @@ impl APU {
|
||||
self.pulse_2.length_timer_high.0 = val;
|
||||
self.pulse_2.reset();
|
||||
}
|
||||
0x09 => (), // Unused, technically noise channel?
|
||||
0x08 | 0x0A | 0x0B => {
|
||||
// TODO: Triangle channel
|
||||
}
|
||||
0x0D => (), // Unused, technically noise channel?
|
||||
0x0C | 0x0E | 0x0F => {
|
||||
// TODO: Noise channel
|
||||
}
|
||||
0x10 => {
|
||||
assert_eq!(val, 0x00);
|
||||
// TODO: implement this value
|
||||
@@ -192,6 +209,12 @@ impl APU {
|
||||
0x11 => {
|
||||
// TODO: load dmc counter with (val & 7F)
|
||||
}
|
||||
0x12 => {
|
||||
// TODO: DMC
|
||||
}
|
||||
0x13 => {
|
||||
// TODO: DMC
|
||||
}
|
||||
0x15 => {
|
||||
self.dmc.enabled = val & 0b0001_0000 != 0;
|
||||
self.noise.enabled = val & 0b0000_1000 != 0;
|
||||
@@ -200,7 +223,7 @@ impl APU {
|
||||
self.pulse_1.enabled = val & 0b0000_0001 != 0;
|
||||
}
|
||||
0x17 => {
|
||||
self.frame_counter.mode_5_step = val & 0b1000_0000 == 0;
|
||||
self.frame_counter.mode_5_step = val & 0b1000_0000 != 0;
|
||||
self.frame_counter.interrupt_enabled = val & 0b0100_0000 == 0;
|
||||
if !self.frame_counter.interrupt_enabled {
|
||||
self.frame_counter.irq = false;
|
||||
@@ -225,24 +248,23 @@ impl APU {
|
||||
pub fn run_one_clock_cycle(&mut self, ppu_cycle: usize) -> bool {
|
||||
if ppu_cycle % 6 == 1 {
|
||||
// APU Frame Counter clock cycle
|
||||
if self.frame_counter.mode_5_step {
|
||||
todo!()
|
||||
} else {
|
||||
if self.frame_counter.count == 3728 {
|
||||
self.q_frame_clock();
|
||||
} else if self.frame_counter.count == 7456 {
|
||||
self.h_frame_clock();
|
||||
} else if self.frame_counter.count == 11185 {
|
||||
self.q_frame_clock();
|
||||
} else if self.frame_counter.count == 14914 {
|
||||
self.frame_counter.irq = self.frame_counter.interrupt_enabled;
|
||||
self.h_frame_clock();
|
||||
} else if self.frame_counter.count == 14915 {
|
||||
self.frame_counter.count = 0;
|
||||
self.frame_counter.irq = self.frame_counter.interrupt_enabled;
|
||||
}
|
||||
}
|
||||
self.frame_counter.count += 1;
|
||||
if self.frame_counter.count == 3728 {
|
||||
self.q_frame_clock();
|
||||
} else if self.frame_counter.count == 7456 {
|
||||
self.h_frame_clock();
|
||||
} else if self.frame_counter.count == 11185 {
|
||||
self.q_frame_clock();
|
||||
} else if self.frame_counter.count == 14914 && !self.frame_counter.mode_5_step {
|
||||
self.frame_counter.irq = self.frame_counter.interrupt_enabled;
|
||||
self.h_frame_clock();
|
||||
} else if self.frame_counter.count == 14915 && !self.frame_counter.mode_5_step {
|
||||
self.frame_counter.count = 0;
|
||||
self.frame_counter.irq = self.frame_counter.interrupt_enabled;
|
||||
} else if self.frame_counter.count == 18640 {
|
||||
self.h_frame_clock();
|
||||
self.frame_counter.count = 0;
|
||||
}
|
||||
|
||||
self.pulse_1.clock();
|
||||
self.pulse_2.clock();
|
||||
|
||||
Reference in New Issue
Block a user