From 3e1b68fc1e8c2733aa503da58a37e52858db41ce Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Mon, 13 Feb 2023 14:37:43 +1100 Subject: [PATCH] more registersf --- src/processor/memory/mmio/apu.rs | 63 +++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/src/processor/memory/mmio/apu.rs b/src/processor/memory/mmio/apu.rs index cf8c4b0..1fe6a37 100644 --- a/src/processor/memory/mmio/apu.rs +++ b/src/processor/memory/mmio/apu.rs @@ -12,11 +12,17 @@ const fn reg(a: Address) -> usize { struct Channel { enabled: bool, + pan_left: bool, + pan_right: bool, } impl Channel { - fn new(enabled: bool) -> Self { - Self { enabled } + fn new(enabled: bool, pan_left: bool, pan_right: bool) -> Self { + Self { + enabled, + pan_left, + pan_right, + } } } @@ -30,18 +36,27 @@ struct Channels { impl Default for Channels { fn default() -> Self { Self { - one: Channel::new(true), - two: Channel::new(false), - three: Channel::new(false), - four: Channel::new(false), + one: Channel::new(true, true, true), + two: Channel::new(false, true, true), + three: Channel::new(false, true, false), + four: Channel::new(false, true, false), } } } +#[derive(Default)] +struct VinEnable { + left: bool, + right: bool, +} + pub struct Apu { mem: [u8; MEM_SIZE], apu_enable: bool, channels: Channels, + vin: VinEnable, + vol_left: u8, + vol_right: u8, } impl Default for Apu { @@ -50,6 +65,9 @@ impl Default for Apu { mem: [0x0; MEM_SIZE], apu_enable: true, channels: Channels::default(), + vin: VinEnable::default(), + vol_left: 7, + vol_right: 7, } } } @@ -71,6 +89,26 @@ impl Apu { fn make_register(&self, addr: Address) -> u8 { match addr { + 0xFF24 => { + // NR50 - Master volume + VIN panning + let mut v = ((self.vol_left << 4) & 0b1110000) | (self.vol_right & 0b111); + v = set_or_clear_bit(v, 7, self.vin.left); + v = set_or_clear_bit(v, 3, self.vin.right); + v + } + 0xFF25 => { + // NR51 - Panning + let mut v = 0; + v = set_or_clear_bit(v, 0, self.channels.one.pan_right); + v = set_or_clear_bit(v, 1, self.channels.two.pan_right); + v = set_or_clear_bit(v, 2, self.channels.three.pan_right); + v = set_or_clear_bit(v, 3, self.channels.four.pan_right); + v = set_or_clear_bit(v, 4, self.channels.one.pan_left); + v = set_or_clear_bit(v, 5, self.channels.two.pan_left); + v = set_or_clear_bit(v, 6, self.channels.three.pan_left); + v = set_or_clear_bit(v, 7, self.channels.four.pan_left); + v + } 0xFF26 => { // NR52 - Sound on/off let mut v = if self.apu_enable { 1 << 7 } else { 0 }; @@ -80,6 +118,9 @@ impl Apu { v = set_or_clear_bit(v, 3, self.channels.four.enabled); v } + // write-only registers + 0xFF13 | 0xFF18 | 0xFF1B | 0xFF1D | 0xFF20 => 0xFF, + // not registers 0xFF15 | 0xFF1F | 0xFF27..0xFF30 => 0xFF, 0x0..0xFF10 | 0xFF40..0xFFFF | 0xFFFF => panic!("non-apu addr in apu"), _ => self.mem[reg(addr)], @@ -95,6 +136,16 @@ impl Apu { 0xFF23 => { self.mem[reg(addr)] = (self.mem[reg(addr)] & 0b10111111) | (data & 0b01000000) } + 0xFF25 => { + self.channels.one.pan_right = get_bit(data, 0); + self.channels.two.pan_right = get_bit(data, 1); + self.channels.three.pan_right = get_bit(data, 2); + self.channels.four.pan_right = get_bit(data, 3); + self.channels.one.pan_left = get_bit(data, 4); + self.channels.two.pan_left = get_bit(data, 5); + self.channels.three.pan_left = get_bit(data, 6); + self.channels.four.pan_left = get_bit(data, 7); + } 0xFF26 => self.apu_enable = (1 << 7) == (data & 0b10000000), 0xFF11..0xFF1A | 0xFF1B | 0xFF1D..0xFF23 | 0xFF24..0xFF40 => self.mem[reg(addr)] = data, 0x0..0xFF10 | 0xFF40..0xFFFF | 0xFFFF => panic!("non-apu addr in apu"),