make registers from apu values

This commit is contained in:
Alex Janka 2023-02-13 14:11:16 +11:00
parent f343075599
commit 0b2378d160

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
processor::memory::{masked_update, Address}, processor::memory::{masked_update, Address},
util::get_bit, util::{get_bit, set_or_clear_bit},
}; };
const MEM_START: usize = 0xFF10; const MEM_START: usize = 0xFF10;
@ -10,14 +10,46 @@ const fn reg(a: Address) -> usize {
(a as usize) - MEM_START (a as usize) - MEM_START
} }
struct Channel {
enabled: bool,
}
impl Channel {
fn new(enabled: bool) -> Self {
Self { enabled }
}
}
struct Channels {
one: Channel,
two: Channel,
three: Channel,
four: Channel,
}
impl Default for Channels {
fn default() -> Self {
Self {
one: Channel::new(true),
two: Channel::new(false),
three: Channel::new(false),
four: Channel::new(false),
}
}
}
pub struct Apu { pub struct Apu {
mem: [u8; MEM_SIZE], mem: [u8; MEM_SIZE],
apu_enable: bool,
channels: Channels,
} }
impl Default for Apu { impl Default for Apu {
fn default() -> Self { fn default() -> Self {
Self { Self {
mem: [0x0; MEM_SIZE], mem: [0x0; MEM_SIZE],
apu_enable: true,
channels: Channels::default(),
} }
} }
} }
@ -31,12 +63,27 @@ impl Apu {
|| addr == 0xFF20 || addr == 0xFF20
|| get_bit(self.mem[reg(0xFF26)], 7) || get_bit(self.mem[reg(0xFF26)], 7)
{ {
self.mem[reg(addr)] self.make_register(addr)
} else { } else {
0xFF 0xFF
} }
} }
fn make_register(&self, addr: Address) -> u8 {
match addr {
0xFF26 => {
// NR52 - Sound on/off
let mut v = if self.apu_enable { 1 << 7 } else { 0 };
v = set_or_clear_bit(v, 0, self.channels.one.enabled);
v = set_or_clear_bit(v, 1, self.channels.two.enabled);
v = set_or_clear_bit(v, 2, self.channels.three.enabled);
v = set_or_clear_bit(v, 3, self.channels.four.enabled);
v
}
_ => self.mem[reg(addr)],
}
}
pub fn mmio_write(&mut self, addr: Address, data: u8) { pub fn mmio_write(&mut self, addr: Address, data: u8) {
match addr { match addr {
0xFF10 => self.masked_io(reg(addr), data, 0b01111111), 0xFF10 => self.masked_io(reg(addr), data, 0b01111111),
@ -46,7 +93,7 @@ impl Apu {
0xFF23 => { 0xFF23 => {
self.mem[reg(addr)] = (self.mem[reg(addr)] & 0b10111111) | (data & 0b01000000) self.mem[reg(addr)] = (self.mem[reg(addr)] & 0b10111111) | (data & 0b01000000)
} }
0xFF26 => self.mem[reg(addr)] = (self.mem[reg(addr)] & 0b1111111) | (data & 0b10000000), 0xFF26 => self.apu_enable = (1 << 7) == (data & 0b10000000),
0xFF11..0xFF1A | 0xFF1B | 0xFF1D..0xFF23 | 0xFF24..0xFF40 => { 0xFF11..0xFF1A | 0xFF1B | 0xFF1D..0xFF23 | 0xFF24..0xFF40 => {
println!("BANNED write in APU: {data:#X} to {addr:#X}") println!("BANNED write in APU: {data:#X} to {addr:#X}")
} }