Updated sn76489

This commit is contained in:
transistor 2022-01-26 19:15:46 -08:00
parent 54bf7a3085
commit 061c13fdc7
2 changed files with 70 additions and 28 deletions

View File

@ -10,7 +10,7 @@ use moa::system::System;
use moa::host::gfx::Frame; use moa::host::gfx::Frame;
use moa::devices::{ClockElapsed, Address, Addressable, Steppable, Transmutable, TransmutableBox, wrap_transmutable}; use moa::devices::{ClockElapsed, Address, Addressable, Steppable, Transmutable, TransmutableBox, wrap_transmutable};
use moa::host::keys::{Key}; use moa::host::keys::{Key};
use moa::host::traits::{Host, HostData, KeyboardUpdater}; use moa::host::traits::{Host, KeyboardUpdater};
pub struct SynthControlsUpdater(mpsc::Sender<(Key, bool)>); pub struct SynthControlsUpdater(mpsc::Sender<(Key, bool)>);
@ -48,6 +48,7 @@ impl Steppable for SynthControl {
system.get_bus().write_u8(0x10, 0x0F)?; system.get_bus().write_u8(0x10, 0x0F)?;
system.get_bus().write_u8(0x10, if state { 0x90 } else { 0x9F })?; system.get_bus().write_u8(0x10, if state { 0x90 } else { 0x9F })?;
}, },
_ => { }, _ => { },
} }
} }

View File

@ -9,13 +9,13 @@ use crate::host::traits::{Host, Audio};
const DEV_NAME: &'static str = "sn76489"; const DEV_NAME: &'static str = "sn76489";
#[derive(Clone)] #[derive(Clone)]
pub struct Channel { pub struct ToneGenerator {
on: bool, on: bool,
attenuation: f32, attenuation: f32,
wave: SquareWave, wave: SquareWave,
} }
impl Channel { impl ToneGenerator {
pub fn new(sample_rate: usize) -> Self { pub fn new(sample_rate: usize) -> Self {
Self { Self {
on: false, on: false,
@ -31,13 +31,13 @@ impl Channel {
self.on = true; self.on = true;
self.attenuation = (attenuation << 1) as f32; self.attenuation = (attenuation << 1) as f32;
} }
println!("set attenuation to {} {}", self.attenuation, self.on); info!("set attenuation to {} {}", self.attenuation, self.on);
} }
pub fn set_counter(&mut self, count: usize) { pub fn set_counter(&mut self, count: usize) {
let frequency = 3_579_545.0 / (count as f32 * 32.0); let frequency = 3_579_545.0 / (count as f32 * 32.0);
self.wave.set_frequency(frequency); self.wave.set_frequency(frequency);
println!("set frequency to {}", frequency); info!("set frequency to {}", frequency);
} }
pub fn get_sample(&mut self) -> f32 { pub fn get_sample(&mut self) -> f32 {
@ -46,11 +46,49 @@ impl Channel {
} }
#[derive(Clone)]
pub struct NoiseGenerator {
on: bool,
attenuation: f32,
}
impl NoiseGenerator {
pub fn new() -> Self {
Self {
on: false,
attenuation: 0.0,
}
}
pub fn set_attenuation(&mut self, attenuation: u8) {
if attenuation == 0x0F {
self.on = false;
} else {
self.on = true;
self.attenuation = (attenuation << 1) as f32;
}
info!("set attenuation to {} {}", self.attenuation, self.on);
}
pub fn set_control(&mut self, bits: u8) {
//let frequency = 3_579_545.0 / (count as f32 * 32.0);
//self.wave.set_frequency(frequency);
//debug!("set frequency to {}", frequency);
}
pub fn get_sample(&mut self) -> f32 {
// TODO this isn't implemented yet
0.0
}
}
pub struct Sn76489 { pub struct Sn76489 {
pub regs: [u8; 8],
pub first_byte: Option<u8>, pub first_byte: Option<u8>,
pub source: Box<dyn Audio>, pub source: Box<dyn Audio>,
pub channels: Vec<Channel>, pub tones: Vec<ToneGenerator>,
pub noise: NoiseGenerator,
} }
impl Sn76489 { impl Sn76489 {
@ -59,10 +97,10 @@ impl Sn76489 {
let sample_rate = source.samples_per_second(); let sample_rate = source.samples_per_second();
Ok(Self { Ok(Self {
regs: [0; 8],
first_byte: None, first_byte: None,
source, source,
channels: vec![Channel::new(sample_rate); 3], tones: vec![ToneGenerator::new(sample_rate); 3],
noise: NoiseGenerator::new(),
}) })
} }
} }
@ -81,12 +119,17 @@ impl Steppable for Sn76489 {
let mut count = 0; let mut count = 0;
for ch in 0..3 { for ch in 0..3 {
if self.channels[ch].on { if self.tones[ch].on {
sample += self.channels[ch].get_sample(); sample += self.tones[ch].get_sample();
count += 1; count += 1;
} }
} }
if self.noise.on {
sample += self.noise.get_sample();
count += 1;
}
if count > 0 { if count > 0 {
buffer[i] = sample / count as f32; buffer[i] = sample / count as f32;
} }
@ -116,25 +159,25 @@ impl Addressable for Sn76489 {
return Ok(()); return Ok(());
} }
if (data[0] & 0x80) == 0 { if (data[0] & 0x80) != 0 {
let reg = (data[0] & 0x70) >> 4;
let value = data[0] & 0x0F;
match reg {
1 => self.tones[0].set_attenuation(value),
3 => self.tones[1].set_attenuation(value),
5 => self.tones[2].set_attenuation(value),
6 => self.noise.set_control(value),
7 => self.noise.set_attenuation(value),
_ => { self.first_byte = Some(data[0]); },
}
} else {
let first = self.first_byte.unwrap_or(0); let first = self.first_byte.unwrap_or(0);
let reg = (first & 0x70) >> 4; let reg = (first & 0x70) >> 4;
let value = ((data[0] as usize & 0x3F) << 4) | (first as usize & 0x0F); let value = ((data[0] as usize & 0x3F) << 4) | (first as usize & 0x0F);
match reg { match reg {
0 => self.channels[0].set_counter(value), 0 => self.tones[0].set_counter(value),
2 => self.channels[1].set_counter(value), 2 => self.tones[1].set_counter(value),
4 => self.channels[2].set_counter(value), 4 => self.tones[2].set_counter(value),
_ => { },
}
} else {
let reg = (data[0] & 0x70) >> 4;
self.first_byte = Some(data[0]);
//self.regs[reg as usize] = data[0] & 0x0F;
let attenuation = data[0] & 0x0F;
match reg {
1 => self.channels[0].set_attenuation(attenuation),
3 => self.channels[1].set_attenuation(attenuation),
5 => self.channels[2].set_attenuation(attenuation),
_ => { }, _ => { },
} }
} }
@ -143,7 +186,6 @@ impl Addressable for Sn76489 {
} }
} }
impl Transmutable for Sn76489 { impl Transmutable for Sn76489 {
fn as_addressable(&mut self) -> Option<&mut dyn Addressable> { fn as_addressable(&mut self) -> Option<&mut dyn Addressable> {
Some(self) Some(self)
@ -154,4 +196,3 @@ impl Transmutable for Sn76489 {
} }
} }