Compare commits

..

No commits in common. "c7e3cb5b35ddbea4f66ad3f29e95484cd3ff391c" and "9e36e86c14b971aea47c8f8873315586cb806818" have entirely different histories.

2 changed files with 48 additions and 83 deletions

View File

@ -1,4 +1,3 @@
use crate::bus::BusIo;
use crate::emu::SM83_CLOCK_SPEED; use crate::emu::SM83_CLOCK_SPEED;
use gen::{AudioBuffer, AudioSender}; use gen::{AudioBuffer, AudioSender};
use types::ch1::{Sweep, SweepDirection}; use types::ch1::{Sweep, SweepDirection};
@ -19,15 +18,15 @@ const SAMPLE_INCREMENT: u64 = SAMPLE_RATE as u64;
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct Apu { pub struct Apu {
ctrl: SoundControl, pub(crate) ctrl: SoundControl,
/// Tone & Sweep /// Tone & Sweep
ch1: Channel1, pub(crate) ch1: Channel1,
/// Tone /// Tone
ch2: Channel2, pub(crate) ch2: Channel2,
/// Wave /// Wave
ch3: Channel3, pub(crate) ch3: Channel3,
/// Noise /// Noise
ch4: Channel4, pub(crate) ch4: Channel4,
// Frame Sequencer // Frame Sequencer
frame_seq_state: FrameSequencerState, frame_seq_state: FrameSequencerState,
@ -39,66 +38,6 @@ pub struct Apu {
buffer: AudioBuffer<(f32, f32)>, buffer: AudioBuffer<(f32, f32)>,
} }
impl BusIo for Apu {
fn read_byte(&self, addr: u16) -> u8 {
match addr & 0x00FF {
0x11 => self.ch1.duty(),
0x12 => self.ch1.envelope(),
0x14 => self.ch1.freq_hi(),
0x16 => self.ch2.duty(),
0x17 => self.ch2.envelope(),
0x19 => self.ch2.freq_hi(),
0x1A => self.ch3.enabled(),
0x1B => self.ch3.len(),
0x1C => self.ch3.volume(),
0x1E => self.ch3.freq_hi(),
0x20 => self.ch4.len(),
0x21 => self.ch4.envelope(),
0x22 => self.ch4.poly(),
0x23 => self.ch4.frequency(),
0x24 => self.ctrl.channel(),
0x25 => self.ctrl.output(),
0x26 => self.ctrl.status(self),
0x30..=0x3F => self.ch3.read_byte(addr),
_ => {
eprintln!("Read 0xFF from unused IO register {:#06X} [APU]", addr);
0xFF
}
}
}
fn write_byte(&mut self, addr: u16, byte: u8) {
match addr & 0x00FF {
0x10 => self.ch1.set_sweep(byte),
0x11 => self.ch1.set_duty(byte),
0x12 => self.ch1.set_envelope(byte),
0x13 => self.ch1.set_freq_lo(byte),
0x14 => self.ch1.set_freq_hi(byte),
0x16 => self.ch2.set_duty(byte),
0x17 => self.ch2.set_envelope(byte),
0x18 => self.ch2.set_freq_lo(byte),
0x19 => self.ch2.set_freq_hi(byte),
0x1A => self.ch3.set_enabled(byte),
0x1B => self.ch3.set_len(byte),
0x1C => self.ch3.set_volume(byte),
0x1D => self.ch3.set_freq_lo(byte),
0x1E => self.ch3.set_freq_hi(byte),
0x20 => self.ch4.set_len(byte),
0x21 => self.ch4.set_envelope(byte),
0x22 => self.ch4.set_poly(byte),
0x23 => self.ch4.set_freq_data(byte),
0x24 => self.ctrl.set_channel(byte),
0x25 => self.ctrl.set_output(byte),
0x26 => self.set_status(byte),
0x30..=0x3F => self.ch3.write_byte(addr, byte),
_ => eprintln!(
"Wrote {:#04X} to unused IO register {:#06X} [APU]",
byte, addr
),
}
}
}
impl Apu { impl Apu {
pub(crate) fn clock(&mut self, div: u16) { pub(crate) fn clock(&mut self, div: u16) {
use FrameSequencerState::*; use FrameSequencerState::*;
@ -672,8 +611,7 @@ pub(crate) struct Channel3 {
freq_lo: u8, freq_lo: u8,
/// 0xFF1E | NR34 - Channel 3 Frequency high /// 0xFF1E | NR34 - Channel 3 Frequency high
freq_hi: FrequencyHigh, freq_hi: FrequencyHigh,
pub(crate) wave_ram: [u8; WAVE_PATTERN_RAM_LEN],
wave_ram: [u8; WAVE_PATTERN_RAM_LEN],
// Length Functionality // Length Functionality
length_timer: u16, length_timer: u16,
@ -682,19 +620,7 @@ pub(crate) struct Channel3 {
offset: u8, offset: u8,
} }
impl BusIo for Channel3 {
fn read_byte(&self, addr: u16) -> u8 {
self.wave_ram[(addr - Self::WAVE_RAM_START_ADDR) as usize]
}
fn write_byte(&mut self, addr: u16, byte: u8) {
self.wave_ram[(addr - Self::WAVE_RAM_START_ADDR) as usize] = byte;
}
}
impl Channel3 { impl Channel3 {
const WAVE_RAM_START_ADDR: u16 = 0xFF30;
/// 0xFF1A | NR30 - Channel 3 Sound on/off /// 0xFF1A | NR30 - Channel 3 Sound on/off
pub(crate) fn enabled(&self) -> u8 { pub(crate) fn enabled(&self) -> u8 {
((self.enabled as u8) << 7) | 0x7F ((self.enabled as u8) << 7) | 0x7F

View File

@ -224,7 +224,25 @@ impl BusIo for Bus {
0x06 => self.timer.modulo, 0x06 => self.timer.modulo,
0x07 => self.timer.ctrl.into(), 0x07 => self.timer.ctrl.into(),
0x0F => self.interrupt_flag().into(), 0x0F => self.interrupt_flag().into(),
0x10..=0x3F => self.apu.read_byte(addr), 0x10 => self.apu.ch1.sweep(),
0x11 => self.apu.ch1.duty(),
0x12 => self.apu.ch1.envelope(),
0x14 => self.apu.ch1.freq_hi(),
0x16 => self.apu.ch2.duty(),
0x17 => self.apu.ch2.envelope(),
0x19 => self.apu.ch2.freq_hi(),
0x1A => self.apu.ch3.enabled(),
0x1B => self.apu.ch3.len(),
0x1C => self.apu.ch3.volume(),
0x1E => self.apu.ch3.freq_hi(),
0x20 => self.apu.ch4.len(),
0x21 => self.apu.ch4.envelope(),
0x22 => self.apu.ch4.poly(),
0x23 => self.apu.ch4.frequency(),
0x24 => self.apu.ctrl.channel(),
0x25 => self.apu.ctrl.output(),
0x26 => self.apu.ctrl.status(&self.apu),
0x30..=0x3F => self.apu.ch3.wave_ram[addr as usize - 0xFF30],
0x40 => self.ppu.ctrl.into(), 0x40 => self.ppu.ctrl.into(),
0x41 => self.ppu.stat.into(), 0x41 => self.ppu.stat.into(),
0x42 => self.ppu.pos.scroll_y, 0x42 => self.ppu.pos.scroll_y,
@ -237,7 +255,7 @@ impl BusIo for Bus {
0x49 => self.ppu.monochrome.obj_palette_1.into(), 0x49 => self.ppu.monochrome.obj_palette_1.into(),
0x4A => self.ppu.pos.window_y, 0x4A => self.ppu.pos.window_y,
0x4B => self.ppu.pos.window_x, 0x4B => self.ppu.pos.window_x,
0x4D => 0xFF, // TODO: CGB Specific Register 0x4D => 0xFF, // CGB Specific Register
_ => { _ => {
eprintln!("Read 0xFF from unused IO register {:#06X}.", addr); eprintln!("Read 0xFF from unused IO register {:#06X}.", addr);
0xFF 0xFF
@ -324,7 +342,28 @@ impl BusIo for Bus {
0x06 => self.timer.modulo = byte, 0x06 => self.timer.modulo = byte,
0x07 => self.timer.ctrl = byte.into(), 0x07 => self.timer.ctrl = byte.into(),
0x0F => self.set_interrupt_flag(byte), 0x0F => self.set_interrupt_flag(byte),
0x10..=0x3F => self.apu.write_byte(addr, byte), 0x10 => self.apu.ch1.set_sweep(byte),
0x11 => self.apu.ch1.set_duty(byte),
0x12 => self.apu.ch1.set_envelope(byte),
0x13 => self.apu.ch1.set_freq_lo(byte),
0x14 => self.apu.ch1.set_freq_hi(byte),
0x16 => self.apu.ch2.set_duty(byte),
0x17 => self.apu.ch2.set_envelope(byte),
0x18 => self.apu.ch2.set_freq_lo(byte),
0x19 => self.apu.ch2.set_freq_hi(byte),
0x1A => self.apu.ch3.set_enabled(byte),
0x1B => self.apu.ch3.set_len(byte),
0x1C => self.apu.ch3.set_volume(byte),
0x1D => self.apu.ch3.set_freq_lo(byte),
0x1E => self.apu.ch3.set_freq_hi(byte),
0x20 => self.apu.ch4.set_len(byte),
0x21 => self.apu.ch4.set_envelope(byte),
0x22 => self.apu.ch4.set_poly(byte),
0x23 => self.apu.ch4.set_freq_data(byte),
0x24 => self.apu.ctrl.set_channel(byte),
0x25 => self.apu.ctrl.set_output(byte),
0x26 => self.apu.set_status(byte),
0x30..=0x3F => self.apu.ch3.wave_ram[addr as usize - 0xFF30] = byte,
0x40 => self.ppu.ctrl = byte.into(), 0x40 => self.ppu.ctrl = byte.into(),
0x41 => self.ppu.stat.update(byte), 0x41 => self.ppu.stat.update(byte),
0x42 => self.ppu.pos.scroll_y = byte, 0x42 => self.ppu.pos.scroll_y = byte,