gb/src/sound.rs

353 lines
6.7 KiB
Rust
Raw Normal View History

2021-01-19 04:54:38 +00:00
use crate::instruction::Cycles;
use bitfield::bitfield;
2021-01-03 08:05:46 +00:00
#[derive(Debug, Clone, Copy, Default)]
pub struct Sound {
2021-01-18 00:58:57 +00:00
pub control: SoundControl,
pub ch1: Channel1,
2021-01-18 00:58:57 +00:00
}
2021-01-19 04:54:38 +00:00
impl Sound {
pub fn step(&mut self, _cycles: Cycles) {
//
}
}
2021-01-18 00:58:57 +00:00
#[derive(Debug, Clone, Copy, Default)]
pub struct SoundControl {
pub channel: ChannelControl,
pub output: SoundOutput,
2021-01-18 00:58:57 +00:00
pub status: SoundStatus,
2021-01-03 08:05:46 +00:00
}
// TODO: What to do about the separation of freq bits
// across multiple registers?
bitfield! {
pub struct FrequencyHigh(u8);
impl Debug;
_, initial: 7;
from into FrequencyType, get_freq_type, set_freq_type: 6;
_, set_freq_high_bits: 2, 0;
}
impl Copy for FrequencyHigh {}
impl Clone for FrequencyHigh {
fn clone(&self) -> Self {
*self
}
}
impl Default for FrequencyHigh {
fn default() -> Self {
Self(0)
}
}
impl From<u8> for FrequencyHigh {
fn from(byte: u8) -> Self {
Self(byte)
}
}
impl From<FrequencyHigh> for u8 {
fn from(duty: FrequencyHigh) -> Self {
duty.0
}
}
bitfield! {
pub struct FrequencyLow(u8);
impl Debug;
pub _, set_freq_bits: 7, 0;
}
impl Copy for FrequencyLow {}
impl Clone for FrequencyLow {
fn clone(&self) -> Self {
*self
}
}
impl Default for FrequencyLow {
fn default() -> Self {
Self(0)
}
}
impl From<u8> for FrequencyLow {
fn from(byte: u8) -> Self {
Self(byte)
}
}
pub fn get_11bit_freq(low: &FrequencyLow, high: FrequencyHigh) -> u16 {
let high_bits = high.0 & 0b111;
(low.0 as u16) << 8 | ((high_bits as u16) << 4)
}
#[derive(Debug, Clone, Copy)]
enum FrequencyType {
2021-01-19 07:36:44 +00:00
Counter = 0,
2021-03-16 00:19:40 +00:00
Consecutive = 1,
}
impl From<u8> for FrequencyType {
fn from(byte: u8) -> Self {
match byte {
0b00 => Self::Counter,
2021-03-16 00:19:40 +00:00
0b01 => Self::Consecutive,
_ => unreachable!("{} is not a valid number for FrequencyType"),
}
}
}
impl Default for FrequencyType {
fn default() -> Self {
Self::Counter
}
}
bitfield! {
pub struct SoundStatus(u8);
impl Debug;
all_enabled, set_all_enabled: 7;
sound_4, _: 3;
sound_3, _: 2;
sound_2, _: 1;
sound_1, _: 0;
}
impl Copy for SoundStatus {}
impl Clone for SoundStatus {
fn clone(&self) -> Self {
*self
}
}
impl Default for SoundStatus {
fn default() -> Self {
Self(0)
}
2021-01-03 08:05:46 +00:00
}
impl From<u8> for SoundStatus {
fn from(byte: u8) -> Self {
Self(byte)
2021-01-03 08:05:46 +00:00
}
}
impl From<SoundStatus> for u8 {
fn from(duty: SoundStatus) -> Self {
duty.0
2021-01-03 08:05:46 +00:00
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct Channel1 {
pub sound_duty: SoundDuty,
pub vol_envelope: VolumeEnvelope,
pub freq_hi: FrequencyHigh,
pub freq_lo: FrequencyLow,
}
bitfield! {
pub struct VolumeEnvelope(u8);
impl Debug;
init_vol, set_init_vol: 7, 4;
from into EnvelopeDirection, direction, set_direction: 3;
sweep_count, set_sweep_count: 2, 0;
}
impl Copy for VolumeEnvelope {}
impl Clone for VolumeEnvelope {
fn clone(&self) -> Self {
*self
}
}
impl Default for VolumeEnvelope {
fn default() -> Self {
Self(0)
}
}
impl From<u8> for VolumeEnvelope {
fn from(byte: u8) -> Self {
Self(byte)
}
}
impl From<VolumeEnvelope> for u8 {
fn from(duty: VolumeEnvelope) -> Self {
duty.0
}
}
#[derive(Debug, Clone, Copy)]
enum EnvelopeDirection {
2021-01-19 07:36:44 +00:00
Decrease = 0,
Increase = 1,
}
impl From<u8> for EnvelopeDirection {
fn from(byte: u8) -> Self {
match byte {
0b00 => Self::Decrease,
0b01 => Self::Increase,
2021-01-19 07:36:44 +00:00
_ => unreachable!(
"{:#04X} is not a possible value for EnvelopeDirection",
byte
),
}
}
}
impl Default for EnvelopeDirection {
fn default() -> Self {
2021-01-19 07:36:44 +00:00
Self::Decrease
}
}
bitfield! {
pub struct SoundDuty(u8);
impl Debug;
from into WavePattern, wave_pattern, set_wave_pattern: 7, 6;
_, set_sound_length: 5, 0; // TODO: Getter only used if bit 6 in NR14 is set
}
impl Copy for SoundDuty {}
impl Clone for SoundDuty {
fn clone(&self) -> Self {
*self
}
}
impl Default for SoundDuty {
fn default() -> Self {
Self(0)
}
}
impl From<u8> for SoundDuty {
fn from(byte: u8) -> Self {
Self(byte)
}
}
impl From<SoundDuty> for u8 {
fn from(duty: SoundDuty) -> Self {
duty.0
}
}
impl From<WavePattern> for u8 {
fn from(pattern: WavePattern) -> Self {
use WavePattern::*;
match pattern {
OneEighth => 0b00,
OneQuarter => 0b01,
OneHalf => 0b10,
ThreeQuarters => 0b11,
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum WavePattern {
2021-01-19 07:36:44 +00:00
OneEighth = 0, // 12.5% ( _-------_-------_------- )
OneQuarter = 1, // 25% ( __------__------__------ )
OneHalf = 2, // 50% ( ____----____----____---- ) (normal)
ThreeQuarters = 3, // 75% ( ______--______--______-- )
}
impl Default for WavePattern {
fn default() -> Self {
Self::OneEighth // Rationale: OneEighth is 0x00
}
}
impl From<u8> for WavePattern {
fn from(byte: u8) -> Self {
match byte {
0b00 => Self::OneEighth,
0b01 => Self::OneQuarter,
0b10 => Self::OneHalf,
0b11 => Self::ThreeQuarters,
_ => unreachable!("{:#04X} is not a valid value for a Sound Wave", byte),
}
}
}
bitfield! {
pub struct SoundOutput(u8);
impl Debug;
snd4_so2, set_snd4_so2: 7;
snd3_so2, set_snd3_so2: 6;
snd2_so2, set_snd2_so2: 5;
snd1_so2, set_snd1_so2: 4;
snd4_so1, set_snd4_so1: 3;
snd3_so1, set_snd3_so1: 2;
snd2_so1, set_snd2_so1: 1;
snd1_so1, set_snd1_so1: 0;
}
impl Copy for SoundOutput {}
impl Clone for SoundOutput {
fn clone(&self) -> Self {
*self
}
}
impl Default for SoundOutput {
fn default() -> Self {
Self(0)
}
}
impl From<u8> for SoundOutput {
fn from(byte: u8) -> Self {
Self(byte)
}
}
2021-01-18 00:58:57 +00:00
impl From<SoundOutput> for u8 {
fn from(duty: SoundOutput) -> Self {
duty.0
}
}
bitfield! {
pub struct ChannelControl(u8);
impl Debug;
vin_so2, set_vin_so2: 7;
so2_level, set_so2_level: 6, 4;
vin_so1, set_vin_so1: 3;
so1_level, set_so1_level: 2, 0;
}
impl Copy for ChannelControl {}
impl Clone for ChannelControl {
fn clone(&self) -> Self {
*self
}
}
impl Default for ChannelControl {
fn default() -> Self {
Self(0)
}
2021-01-18 00:58:57 +00:00
}
impl From<u8> for ChannelControl {
fn from(byte: u8) -> Self {
Self(byte)
2021-01-18 00:58:57 +00:00
}
}
impl From<ChannelControl> for u8 {
fn from(duty: ChannelControl) -> Self {
duty.0
2021-01-18 00:58:57 +00:00
}
}