1use crate::apu::components::{Envelope, PulseTimer, StandardLengthCounter, TimerTickEffect}; 2use bincode::{Decode, Encode}; 3use jgenesis_common::num::GetBit; 4 5#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Encode, Decode)] 6enum DutyCycle { 7 #[default] 8 OneEighth, 9 OneFourth, 10 OneHalf, 11 ThreeFourths, 12} 13 14impl DutyCycle { 15 fn waveform_step(self, phase: u8) -> bool { 16 match self { 17 // 00000001 18 Self::OneEighth => 0b1000_0000_u8.bit(phase), 19 // 10000001 20 Self::OneFourth => 0b1000_0001_u8.bit(phase), 21 // 10000111 22 Self::OneHalf => 0b1110_0001_u8.bit(phase), 23 // 01111110 24 Self::ThreeFourths => 0b0111_1110_u8.bit(phase), 25 } 26 } 27 28 fn from_byte(byte: u8) -> Self { 29 match (byte >> 6) & 0x03 { 30 0x00 => Self::OneEighth, 31 0x01 => Self::OneFourth, 32 0x02 => Self::OneHalf, 33 0x03 => Self::ThreeFourths, 34 _ => unreachable!("value & 0x03 is always <= 0x03"), 35 } 36 } 37 38 fn to_bits(self) -> u8 { 39 match self { 40 Self::OneEighth => 0x00, 41 Self::OneFourth => 0x40, 42 Self::OneHalf => 0x80, 43 Self::ThreeFourths => 0xC0, 44 } 45 } 46} 47 48#[derive(Debug, Clone, Encode, Decode)] 49struct SweepUnit { 50 enabled: bool, 51 shadow_frequency: u16, 52 counter: u8, 53 period: u8, 54 shift: u8, 55 negate: bool, 56 calculated_with_negate_since_trigger: bool, 57} 58 59impl SweepUnit { 60 fn new() -> Self { 61 Self { 62 enabled: false, 63 shadow_frequency: 0, 64 counter: 0, 65 period: 0, 66 shift: 0, 67 negate: false, 68 calculated_with_negate_since_trigger: false, 69 } 70 } 71 72 fn clock(&mut self, timer: &mut PulseTimer, channel_enabled: &mut bool) { 73 if !self.enabled { 74 return; 75 } 76 77 self.counter -= 1; 78 if self.counter == 0 { 79 self.counter = self.counter_reload_value(); 80 81 if self.period == 0 { 82 // Period of 0 disables sweep updates (but not the sweep unit counter; a period 83 // of 0 is treated as 8 as far as the counter is concerned) 84 return; 85 } 86 87 let next_frequency = self.calculate_next_frequency(); 88 if next_frequency <= 2047 && self.shift != 0 { 89 self.shadow_frequency = next_frequency; 90 timer.write_frequency(next_frequency); 91 92 // When sweep adjusts frequency, it immediately runs another frequency calculation 93 // and will disable the channel if the second calculation overflows 94 if self.calculate_next_frequency() > 2047 { 95 *channel_enabled = false; 96 } 97 } else if next_frequency > 2047 { 98 *channel_enabled = false; 99 } 100 } 101 } 102 103 fn calculate_next_frequency(&mut self) -> u16 { 104 let mut delta = self.shadow_frequency >> self.shift; 105 if self.negate { 106 delta = (!delta).wrapping_add(1); 107 self.calculated_with_negate_since_trigger = true; 108 } 109 110 self.shadow_frequency.wrapping_add(delta) 111 } 112 113 fn trigger(&mut self, timer: PulseTimer, channel_enabled: &mut bool) { 114 self.shadow_frequency = timer.frequency(); 115 self.counter = self.counter_reload_value(); 116 117 self.enabled = self.period != 0 || self.shift != 0; 118 119 self.calculated_with_negate_since_trigger = false; 120 121 // If shift is non-zero, trigger immediately runs a frequency calculation and will disable 122 // the channel if it overflows 123 if self.shift != 0 && self.calculate_next_frequency() > 2047 { 124 *channel_enabled = false; 125 } 126 } 127 128 fn counter_reload_value(&self) -> u8 { 129 if self.period == 0 { 8 } else { self.period } 130 } 131 132 fn read_register(&self) -> u8 { 133 0x80 | (self.period << 4) | (u8::from(self.negate) << 3) | self.shift 134 } 135 136 fn write_register(&mut self, value: u8, channel_enabled: &mut bool) { 137 self.period = (value >> 4) & 0x07; 138 self.negate = value.bit(3); 139 self.shift = value & 0x07; 140 141 if self.counter == 0 { 142 self.counter = self.period; 143 } 144 145 if self.calculated_with_negate_since_trigger && !self.negate { 146 // If the negate flag is cleared after frequency was calculated with it set at least 147 // once, the channel is immediately disabled 148 *channel_enabled = false; 149 } 150 } 151} 152 153#[derive(Debug, Clone, Encode, Decode)] 154pub struct PulseChannel { 155 duty_cycle: DutyCycle, 156 length_counter: StandardLengthCounter, 157 envelope: Envelope, 158 sweep: SweepUnit, 159 timer: PulseTimer, 160 channel_enabled: bool, 161 dac_enabled: bool, 162 suppress_output: bool, 163} 164 165impl Default for PulseChannel { 166 fn default() -> Self { 167 Self::new() 168 } 169} 170 171impl PulseChannel { 172 #[must_use] 173 pub fn new() -> Self { 174 Self { 175 duty_cycle: DutyCycle::default(), 176 length_counter: StandardLengthCounter::new(), 177 envelope: Envelope::new(), 178 sweep: SweepUnit::new(), 179 timer: PulseTimer::new(), 180 channel_enabled: false, 181 dac_enabled: false, 182 suppress_output: true, 183 } 184 } 185 186 pub fn clock_sweep(&mut self) { 187 self.sweep.clock(&mut self.timer, &mut self.channel_enabled); 188 } 189 190 pub fn clock_length_counter(&mut self) { 191 self.length_counter.clock(&mut self.channel_enabled); 192 } 193 194 pub fn clock_envelope(&mut self) { 195 self.envelope.clock(); 196 } 197 198 pub fn tick_m_cycle(&mut self) { 199 // Obscure behavior: After power-on, pulse channels do not progress through their duty 200 // cycles until after triggering 201 if !self.channel_enabled { 202 return; 203 } 204 205 // More obscure behavior: After power-on, pulse channels output a constant 0 until after 206 // the first phase increment 207 let tick = self.timer.tick(); 208 self.suppress_output &= tick != TimerTickEffect::Clocked; 209 } 210 211 #[must_use] 212 pub fn sample(&self) -> Option<u8> { 213 if !self.dac_enabled { 214 return None; 215 } 216 217 if self.suppress_output { 218 return Some(0); 219 } 220 221 let waveform_step = self.duty_cycle.waveform_step(self.timer.phase); 222 Some(u8::from(waveform_step) * self.envelope.volume) 223 } 224 225 #[must_use] 226 pub fn volume(&self) -> u8 { 227 if !self.dac_enabled || self.suppress_output { 228 return 0; 229 } 230 231 self.envelope.volume 232 } 233 234 #[must_use] 235 pub fn read_register_0(&self) -> u8 { 236 self.sweep.read_register() 237 } 238 239 pub fn write_register_0(&mut self, value: u8) { 240 // NR10: Pulse 1 sweep control 241 self.sweep.write_register(value, &mut self.channel_enabled); 242 243 log::trace!("NR10 write, sweep: {:?}", self.sweep); 244 } 245 246 #[must_use] 247 pub fn read_register_1(&self) -> u8 { 248 0x3F | self.duty_cycle.to_bits() 249 } 250 251 pub fn write_register_1(&mut self, value: u8, apu_enabled: bool) { 252 // NR11/NR21: Pulse duty cycle and length counter reload 253 if apu_enabled { 254 self.duty_cycle = DutyCycle::from_byte(value); 255 } 256 257 self.length_counter.load(value); 258 259 log::trace!("NRx1 write"); 260 log::trace!(" Duty cycle: {:?}", self.duty_cycle); 261 log::trace!(" Length counter: {}", self.length_counter.counter); 262 } 263 264 #[must_use] 265 pub fn read_register_2(&self) -> u8 { 266 self.envelope.read_register() 267 } 268 269 pub fn write_register_2(&mut self, value: u8) { 270 // NR12/NR22: Pulse envelope control 271 self.envelope.write_register(value); 272 self.dac_enabled = value & 0xF8 != 0; 273 274 if !self.dac_enabled { 275 // Disabling DAC always disables the channel 276 self.channel_enabled = false; 277 } 278 279 log::trace!("NRx2 write"); 280 log::trace!(" Envelope: {:?}", self.envelope); 281 log::trace!(" DAC enabled: {}", self.dac_enabled); 282 } 283 284 pub fn write_register_3(&mut self, value: u8) { 285 // NR13/NR23: Pulse frequency low bits 286 let just_reloaded = self.timer.just_reloaded(); 287 self.timer.write_frequency_low(value); 288 289 // If the timer just reloaded, update the counter to the new period. 290 // This is a hack to work around the fact that the write actually occurred mid-M-cycle, but 291 // the emulator is processing it post-M-cycle 292 if just_reloaded { 293 self.timer.trigger(); 294 } 295 296 log::trace!("NRx3 write"); 297 log::trace!(" Timer frequency: {}", self.timer.frequency()); 298 } 299 300 #[must_use] 301 pub fn read_register_4(&self) -> u8 { 302 0xBF | (u8::from(self.length_counter.enabled) << 6) 303 } 304 305 pub fn write_register_4(&mut self, value: u8, frame_sequencer_step: u8) { 306 // NR14/NR24: Pulse frequency high bits + length counter enabled + trigger 307 let timer_just_reloaded = self.timer.just_reloaded(); 308 self.timer.write_frequency_high(value); 309 self.length_counter.set_enabled( 310 value.bit(6), 311 frame_sequencer_step, 312 &mut self.channel_enabled, 313 ); 314 315 // If the timer just reloaded, update the counter to the new period. 316 // This is a hack to work around the fact that the write actually occurred mid-M-cycle, but 317 // the emulator is processing it post-M-cycle 318 if timer_just_reloaded { 319 self.timer.trigger(); 320 } 321 322 if value.bit(7) { 323 // Channel triggered 324 let prev_enabled = self.channel_enabled; 325 self.channel_enabled = true; 326 327 self.length_counter.trigger(frame_sequencer_step); 328 self.envelope.trigger(); 329 self.timer.trigger(); 330 self.sweep.trigger(self.timer, &mut self.channel_enabled); 331 332 self.channel_enabled &= self.dac_enabled; 333 334 if !prev_enabled && self.channel_enabled { 335 // Not sure this is accurate, but adding a 1-cycle delay to the first phase increment 336 // after power-on fixes voice samples in Keitai Denjuu Telefang 337 self.timer.counter += 1; 338 } 339 } 340 341 log::trace!("NRx4 write"); 342 log::trace!(" Timer frequency: {}", self.timer.frequency()); 343 log::trace!(" Length counter enabled: {}", self.length_counter.enabled); 344 log::trace!(" Triggered: {}", value.bit(7)); 345 } 346 347 #[must_use] 348 pub fn enabled(&self) -> bool { 349 self.channel_enabled 350 } 351}