more registersf
This commit is contained in:
parent
2bc9d0f665
commit
3e1b68fc1e
|
@ -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"),
|
||||
|
|
Loading…
Reference in a new issue