Skip to content

Commit

Permalink
Merge pull request #54 from YushiOMOTE/add-pcm-registers
Browse files Browse the repository at this point in the history
Add PCM registers
  • Loading branch information
YushiOMOTE authored Jul 29, 2024
2 parents a0d14f0 + 785976d commit 1c2b57e
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ fn main() {
* OAM bug is not yet supported.
* Sound
* The most features are functioning.
* PCM registers are always emulated for sound tests.
* Joypad
* Timer
* Serial
Expand Down
18 changes: 13 additions & 5 deletions core/src/apu/dac.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#[derive(Debug, Clone)]
pub struct Dac {
power: bool,
amp: isize,
digital_amp: usize,
analog_amp: isize,
}

impl Dac {
pub fn new() -> Self {
Self {
power: false,
amp: 0,
digital_amp: 0,
analog_amp: 0,
}
}

Expand All @@ -19,16 +21,22 @@ impl Dac {

assert!(amp < 16);

self.digital_amp = amp;

// [0, 15] digital amp is mapped to [-8, 8]
self.amp = match amp {
self.analog_amp = match amp {
0..=7 => amp as isize - 8,
8..=15 => amp as isize - 7,
_ => unreachable!(),
};
}

pub fn amp(&self) -> isize {
self.amp
self.analog_amp
}

pub fn pcm(&self) -> usize {
self.digital_amp
}

pub fn on(&self) -> bool {
Expand All @@ -41,6 +49,6 @@ impl Dac {

pub fn power_off(&mut self) {
self.power = false;
self.amp = 0;
self.analog_amp = 0;
}
}
26 changes: 26 additions & 0 deletions core/src/apu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ struct Nr52 {
power_on: bool,
}

#[bitfield(u8)]
struct Pcm {
#[bits(4)]
low: usize,
#[bits(4)]
high: usize,
}

impl Apu {
pub fn new(hw: HardwareHandle) -> Self {
let mixer = Mixer::new();
Expand Down Expand Up @@ -284,6 +292,24 @@ impl Apu {
}
}

/// Read PCM12 register
pub fn read_pcm12(&self) -> u8 {
let pcm = Pcm::default()
.with_low(self.tones[0].pcm())
.with_high(self.tones[1].pcm());

pcm.into_bits()
}

/// Read PCM34 register
pub fn read_pcm34(&self) -> u8 {
let pcm = Pcm::default()
.with_low(self.wave.pcm())
.with_high(self.noise.pcm());

pcm.into_bits()
}

fn sync_all(&mut self) {
for (i, tone) in self.tones.iter().enumerate() {
self.mixer.sync_tone(i, tone.clone());
Expand Down
4 changes: 4 additions & 0 deletions core/src/apu/noise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ impl Noise {
pub fn amp(&self) -> isize {
self.dac.amp()
}

pub fn pcm(&self) -> usize {
self.dac.pcm()
}
}

#[derive(Debug, Clone)]
Expand Down
4 changes: 4 additions & 0 deletions core/src/apu/tone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,4 +309,8 @@ impl Tone {
pub fn amp(&self) -> isize {
self.dac.amp()
}

pub fn pcm(&self) -> usize {
self.dac.pcm()
}
}
4 changes: 4 additions & 0 deletions core/src/apu/wave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,4 +374,8 @@ impl Wave {
pub fn amp(&self) -> isize {
self.dac.amp()
}

pub fn pcm(&self) -> usize {
self.dac.pcm()
}
}
2 changes: 2 additions & 0 deletions core/src/mmu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ impl Mmu {
0xff6a => todo!("cgb bg palette data"),
0xff6b => self.gpu.read_obj_color_palette(),
0xff70 => self.wram.get_bank(),
0xff76 => self.apu.read_pcm12(),
0xff77 => self.apu.read_pcm34(),
0x0000..=0xfeff | 0xff80..=0xffff => unreachable!("read non-i/o addr={:04x}", addr),
_ => {
warn!("read unknown i/o addr={:04x}", addr);
Expand Down

0 comments on commit 1c2b57e

Please sign in to comment.