diff --git a/emulator/peripherals/yamaha/src/ym2612.rs b/emulator/peripherals/yamaha/src/ym2612.rs index 1342f62..8663107 100644 --- a/emulator/peripherals/yamaha/src/ym2612.rs +++ b/emulator/peripherals/yamaha/src/ym2612.rs @@ -99,7 +99,7 @@ impl Channel { self.operators[3].get_sample(modulator2) }, OperatorAlgorithm::A1 => { - let sample1 = (self.operators[0].get_sample(0.0) + self.operators[1].get_sample(0.0)) / 2.0; + let sample1 = self.operators[0].get_sample(0.0) + self.operators[1].get_sample(0.0); let sample2 = self.operators[2].get_sample(sample1); let sample3 = self.operators[3].get_sample(sample2); sample3 @@ -107,7 +107,7 @@ impl Channel { OperatorAlgorithm::A2 => { let sample1 = self.operators[1].get_sample(0.0); let sample2 = self.operators[2].get_sample(sample1); - let sample3 = (self.operators[0].get_sample(0.0) + sample2) / 2.0; + let sample3 = self.operators[0].get_sample(0.0) + sample2; let sample4 = self.operators[3].get_sample(sample3); sample4 }, @@ -115,7 +115,7 @@ impl Channel { let sample1 = self.operators[0].get_sample(0.0); let sample2 = self.operators[1].get_sample(sample1); let sample3 = self.operators[2].get_sample(0.0); - let sample4 = self.operators[3].get_sample((sample2 + sample3) / 2.0); + let sample4 = self.operators[3].get_sample(sample2 + sample3); sample4 }, OperatorAlgorithm::A4 => { @@ -123,24 +123,24 @@ impl Channel { let sample2 = self.operators[1].get_sample(sample1); let sample3 = self.operators[2].get_sample(0.0); let sample4 = self.operators[3].get_sample(sample3); - (sample2 + sample4) / 2.0 + sample2 + sample4 }, OperatorAlgorithm::A5 => { let sample1 = self.operators[0].get_sample(0.0); - let sample2 = (self.operators[1].get_sample(sample1) + self.operators[2].get_sample(sample1) + self.operators[3].get_sample(sample1)) / 3.0; + let sample2 = self.operators[1].get_sample(sample1) + self.operators[2].get_sample(sample1) + self.operators[3].get_sample(sample1); sample2 }, OperatorAlgorithm::A6 => { let sample1 = self.operators[0].get_sample(0.0); let sample2 = self.operators[1].get_sample(sample1); - (sample2 + self.operators[2].get_sample(0.0) + self.operators[3].get_sample(0.0)) / 3.0 + sample2 + self.operators[2].get_sample(0.0) + self.operators[3].get_sample(0.0) }, OperatorAlgorithm::A7 => { let sample = self.operators[0].get_sample(0.0) + self.operators[1].get_sample(0.0) + self.operators[2].get_sample(0.0) + self.operators[3].get_sample(0.0); - sample / 4.0 + sample }, } } @@ -158,6 +158,16 @@ pub struct Ym2612 { pub dac_enabled: bool, pub dac: VecDeque, + + pub timer_a_enable: bool, + pub timer_a: u16, + pub timer_a_current: u16, + pub timer_a_overflow: bool, + + pub timer_b_enable: bool, + pub timer_b: u8, + pub timer_b_current: u8, + pub timer_b_overflow: bool, } impl Ym2612 { @@ -168,59 +178,101 @@ impl Ym2612 { source, selected_reg_0: None, selected_reg_1: None, + channels: vec![Channel::new(sample_rate); 8], channel_frequencies: [(0, 0); CHANNELS], + dac_enabled: false, dac: VecDeque::with_capacity(100), + + timer_a_enable: false, + timer_a: 0, + timer_a_current: 0, + timer_a_overflow: false, + + timer_b_enable: false, + timer_b: 0, + timer_b_current: 0, + timer_b_overflow: false, }) } pub fn set_register(&mut self, bank: usize, reg: usize, data: u8) { - if reg == 0x28 { - let ch = (data as usize) & 0x07; - self.channels[ch].on = data >> 4; - self.channels[ch].reset(); - println!("Note: {}: {:x}", ch, self.channels[ch].on); - } else if reg == 0x2a { - if self.dac_enabled { - for _ in 0..3 { - self.dac.push_back(data); - } - } - } else if reg == 0x2b { - self.dac_enabled = data & 0x80 != 0; - } else if (reg & 0xF0) == 0x30 { - let (ch, op) = get_ch_op(bank, reg); - let multiplier = if data == 0 { 0.5 } else { (data & 0x0F) as f32 }; - let frequency = self.channels[ch].base_frequency; - debug!("{}: channel {} operator {} set to multiplier {}", DEV_NAME, ch + 1, op + 1, multiplier); - self.channels[ch].operators[op].set_multiplier(frequency, multiplier) - } else if reg >= 0xA4 && reg <= 0xA6 { - let ch = (reg & 0x07) - 4 + (bank * 3); - self.channel_frequencies[ch].1 = (self.channel_frequencies[ch].1 & 0xFF) | ((data as u16) & 0x07) << 8; - self.channel_frequencies[ch].0 = (data & 0x38) >> 3; - } else if reg >= 0xA0 && reg <= 0xA2 { - let ch = (reg & 0x07) + (bank * 3); - self.channel_frequencies[ch].1 = (self.channel_frequencies[ch].1 & 0xFF00) | data as u16; + match reg { + 0x24 => { + self.timer_a = (self.timer_a & 0x3) | ((data as u16) << 2); + }, + 0x25 => { + self.timer_a = (self.timer_a & 0xFFFC) | ((data as u16) & 0x03); + }, + 0x26 => { + self.timer_b = data; + }, + 0x27 => { + //if (data >> 5) & 0x1 { + // self.timer_b + }, - let frequency = fnumber_to_frequency(self.channel_frequencies[ch]); - debug!("{}: channel {} set to frequency {}", DEV_NAME, ch + 1, frequency); - self.channels[ch].set_frequency(frequency); - } else if reg >= 0xB0 && reg <= 0xB2 { - let ch = (reg & 0x07) + (bank * 3); - self.channels[ch].algorithm = match data & 0x07 { - 0 => OperatorAlgorithm::A0, - 1 => OperatorAlgorithm::A1, - 2 => OperatorAlgorithm::A2, - 3 => OperatorAlgorithm::A3, - 4 => OperatorAlgorithm::A4, - 5 => OperatorAlgorithm::A5, - 6 => OperatorAlgorithm::A6, - 7 => OperatorAlgorithm::A7, - _ => OperatorAlgorithm::A0, - }; - } else { - warning!("{}: !!! unhandled write to register {:0x} with {:0x}", DEV_NAME, reg, data); + 0x28 => { + let ch = (data as usize) & 0x07; + self.channels[ch].on = data >> 4; + self.channels[ch].reset(); + println!("Note: {}: {:x}", ch, self.channels[ch].on); + }, + + 0x2a => { + if self.dac_enabled { + for _ in 0..3 { + self.dac.push_back(data); + } + } + }, + + 0x2b => { + self.dac_enabled = data & 0x80 != 0; + }, + + reg if (reg & 0xF0) == 0x30 => { + let (ch, op) = get_ch_op(bank, reg); + let multiplier = if data == 0 { 0.5 } else { (data & 0x0F) as f32 }; + let frequency = self.channels[ch].base_frequency; + debug!("{}: channel {} operator {} set to multiplier {}", DEV_NAME, ch + 1, op + 1, multiplier); + self.channels[ch].operators[op].set_multiplier(frequency, multiplier) + }, + + reg if reg >= 0xA0 && reg <= 0xA2 => { + let ch = (reg & 0x07) + (bank * 3); + self.channel_frequencies[ch].1 = (self.channel_frequencies[ch].1 & 0xFF00) | data as u16; + + let frequency = fnumber_to_frequency(self.channel_frequencies[ch]); + debug!("{}: channel {} set to frequency {}", DEV_NAME, ch + 1, frequency); + self.channels[ch].set_frequency(frequency); + }, + + reg if reg >= 0xA4 && reg <= 0xA6 => { + let ch = (reg & 0x07) - 4 + (bank * 3); + self.channel_frequencies[ch].1 = (self.channel_frequencies[ch].1 & 0xFF) | ((data as u16) & 0x07) << 8; + self.channel_frequencies[ch].0 = (data & 0x38) >> 3; + }, + + reg if reg >= 0xB0 && reg <= 0xB2 => { + let ch = (reg & 0x07) + (bank * 3); + self.channels[ch].algorithm = match data & 0x07 { + 0 => OperatorAlgorithm::A0, + 1 => OperatorAlgorithm::A1, + 2 => OperatorAlgorithm::A2, + 3 => OperatorAlgorithm::A3, + 4 => OperatorAlgorithm::A4, + 5 => OperatorAlgorithm::A5, + 6 => OperatorAlgorithm::A6, + 7 => OperatorAlgorithm::A7, + _ => OperatorAlgorithm::A0, + }; + }, + + _ => { + warning!("{}: !!! unhandled write to register {:0x} with {:0x}", DEV_NAME, reg, data); + }, } } } @@ -297,7 +349,7 @@ impl Addressable for Ym2612 { match addr { 0 | 1 | 2 | 3 => { // Read the status byte (busy/overflow) - data[0] = 0; + data[0] = 0 | ((self.timer_a_overflow as u8) << 1) | (self.timer_b_overflow as u8); } _ => { warning!("{}: !!! unhandled read from {:0x}", DEV_NAME, addr);