make registers from apu values
This commit is contained in:
parent
f343075599
commit
0b2378d160
|
@ -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}")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue