Skip to content
Snippets Groups Projects
Verified Commit 6395f11d authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

feat: initial PPU read and write code

parent 840873b1
No related branches found
No related tags found
1 merge request!19Initial tentative audio support 🔉
Pipeline #2257 failed
use crate::warnln;
pub struct Apu {
ch1_sweep_slope: u8,
ch1_sweep_increase: bool,
ch1_sweep_pace: u8,
ch1_length_timer: u8,
ch1_wave_duty: u8,
ch1_pace: u8,
ch1_direction: u8,
ch1_volume: u8,
ch1_wave_length: u16,
ch1_sound_length: bool,
ch1_enabled: bool,
ch2_length_timer: u8,
ch2_wave_duty: u8,
ch2_pace: u8,
ch2_direction: u8,
ch2_volume: u8,
ch2_wave_length: u16,
ch2_sound_length: bool,
ch2_enabled: bool,
}
impl Apu {
pub fn new() -> Self {
Self {}
Self {
ch1_sweep_slope: 0x0,
ch1_sweep_increase: false,
ch1_sweep_pace: 0x0,
ch1_length_timer: 0x0,
ch1_wave_duty: 0x0,
ch1_pace: 0x0,
ch1_direction: 0x0,
ch1_volume: 0x0,
ch1_wave_length: 0x0,
ch1_sound_length: false,
ch1_enabled: false,
ch2_length_timer: 0x0,
ch2_wave_duty: 0x0,
ch2_pace: 0x0,
ch2_direction: 0x0,
ch2_volume: 0x0,
ch2_wave_length: 0x0,
ch2_sound_length: false,
ch2_enabled: false,
}
}
pub fn read(&mut self, addr: u16) -> u8 {
match addr {
0xff26 => 1 as u8, // todo implement this
_ => 0x00
_ => {
warnln!("Reading from unknown APU location 0x{:04x}", addr);
0xff
}
}
}
pub fn write(&mut self, addr: u16, value: u8) {
match addr {
0xff26 => {
// @todo implement the logic here
},
_ => {}
// 0xFF10 — NR10: Channel 1 length timer & duty cycle
0xff10 => {
self.ch1_sweep_slope = value & 0x03;
self.ch1_sweep_increase = value & 0x04 == 0x04;
self.ch1_sweep_pace = (value & 0x70) >> 4;
}
// 0xFF11 — NR11: Channel 1 length timer & duty cycle
0xff11 => {
self.ch1_length_timer = value & 0x3f;
self.ch1_wave_duty = (value & 0xc0) >> 6;
}
// 0xFF12 — NR12: Channel 1 volume & envelope
0xff12 => {
self.ch1_pace = value & 0x07;
self.ch1_direction = (value & 0x08) >> 3;
self.ch1_volume = (value & 0xf0) >> 4;
}
// 0xFF13 — NR13: Channel 1 wavelength low
0xff13 => {
self.ch1_wave_length = (self.ch1_wave_length & 0xff00) | value as u16;
}
// 0xFF14 — NR14: Channel 1 wavelength high & control
0xff14 => {
self.ch1_wave_length =
(self.ch1_wave_length & 0x00ff) | (((value & 0x07) as u16) << 8);
self.ch1_sound_length |= value & 0x40 == 0x40;
self.ch1_enabled |= value & 0x80 == 0x80;
println!("CH1 Enabled {}", self.ch1_enabled);
}
// 0xFF16 — NR21: Channel 2 length timer & duty cycle
0xff16 => {
self.ch2_length_timer = value & 0x3f;
self.ch2_wave_duty = (value & 0xc0) >> 6;
}
// 0xFF17 — NR22: Channel 2 volume & envelope
0xff17 => {
self.ch2_pace = value & 0x07;
self.ch2_direction = (value & 0x08) >> 3;
self.ch2_volume = (value & 0xf0) >> 4;
}
// 0xFF18 — NR23: Channel 2 wavelength low
0xff18 => {
self.ch2_wave_length = (self.ch2_wave_length & 0xff00) | value as u16;
}
// 0xFF19 — NR24: Channel 1 wavelength high & control
0xff19 => {
self.ch2_wave_length =
(self.ch2_wave_length & 0x00ff) | (((value & 0x07) as u16) << 8);
self.ch2_sound_length |= value & 0x40 == 0x40;
self.ch2_enabled |= value & 0x80 == 0x80;
println!("CH2 Enabled {}", self.ch2_enabled);
}
_ => warnln!("Writing in unknown APU location 0x{:04x}", addr),
}
}
}
use crate::{
apu::Apu,
cpu::Cpu,
data::{BootRom, CGB_BOOT, DMG_BOOT, DMG_BOOTIX, MGB_BOOTIX, SGB_BOOT},
gen::{COMPILATION_DATE, COMPILATION_TIME, COMPILER, COMPILER_VERSION},
......@@ -7,7 +8,7 @@ use crate::{
ppu::{Ppu, PpuMode, Tile, FRAME_BUFFER_SIZE},
rom::Cartridge,
timer::Timer,
util::read_file, apu::Apu,
util::read_file,
};
#[cfg(feature = "wasm")]
......
use crate::{debugln, pad::Pad, ppu::Ppu, rom::Cartridge, timer::Timer, apu::Apu};
use crate::{apu::Apu, debugln, pad::Pad, ppu::Ppu, rom::Cartridge, timer::Timer};
pub const BOOT_SIZE: usize = 2304;
pub const RAM_SIZE: usize = 8192;
......@@ -162,6 +162,7 @@ impl Mmu {
0x00
}
},
0x10..=26 | 0x30..=0x37 => self.apu.read(addr),
0x40 | 0x50 | 0x60 | 0x70 => self.ppu.read(addr),
_ => {
debugln!("Reading from unknown IO control 0x{:04x}", addr);
......@@ -232,6 +233,7 @@ impl Mmu {
0x04..=0x07 => self.timer.write(addr, value),
_ => debugln!("Writing to unknown IO control 0x{:04x}", addr),
},
0x10..=26 | 0x30..=0x37 => self.apu.write(addr, value),
0x40 | 0x60 | 0x70 => {
match addr & 0x00ff {
// 0xFF46 — DMA: OAM DMA source address & start
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment