psg.rsannotatedpsg.rssource331 lines · 11.1 KB · raw
1//! PSG (programmable sound generator) channels
2//!
3//! Mostly the same as the Game Boy Color APU channels, though the wavetable channel works a bit differently
4
5mod wavetable;
6
7use crate::apu::psg::wavetable::WavetableChannel;
8use bincode::{Decode, Encode};
9use gb_core::apu::StereoControl;
10use gb_core::apu::noise::NoiseChannel;
11use gb_core::apu::pulse::PulseChannel;
12use jgenesis_common::num::GetBit;
13use std::array;
14
15// Number of 1 MHz cycles for a tick rate of 512 Hz
16const FRAME_SEQUENCER_DIVIDER: u64 = (1 << 20) / 512;
17
18#[derive(Debug, Clone, Encode, Decode)]
19pub struct Psg {
20    odd_tick: bool,
21    pulse_1: PulseChannel,
22    pulse_2: PulseChannel,
23    wavetable: WavetableChannel,
24    noise: NoiseChannel,
25    stereo_control: StereoControl,
26    frame_sequencer_step: u8,
27    frame_sequencer_divider: u64,
28}
29
30impl Psg {
31    pub fn new() -> Self {
32        Self {
33            odd_tick: false,
34            pulse_1: PulseChannel::new(),
35            pulse_2: PulseChannel::new(),
36            wavetable: WavetableChannel::new(),
37            noise: NoiseChannel::new(),
38            stereo_control: StereoControl::zero(),
39            frame_sequencer_step: 0,
40            frame_sequencer_divider: FRAME_SEQUENCER_DIVIDER,
41        }
42    }
43
44    pub fn tick_2mhz(&mut self, apu_enabled: bool) {
45        self.odd_tick = !self.odd_tick;
46        if !self.odd_tick {
47            self.tick_frame_sequencer(apu_enabled);
48
49            self.pulse_1.tick_m_cycle();
50            self.pulse_2.tick_m_cycle();
51            self.noise.tick_m_cycle();
52        }
53
54        self.wavetable.tick_2mhz();
55    }
56
57    fn tick_frame_sequencer(&mut self, apu_enabled: bool) {
58        self.frame_sequencer_divider -= 1;
59        if self.frame_sequencer_divider != 0 {
60            return;
61        }
62        self.frame_sequencer_divider = FRAME_SEQUENCER_DIVIDER;
63
64        self.frame_sequencer_step = (self.frame_sequencer_step + 1) % 8;
65
66        if !apu_enabled {
67            return;
68        }
69
70        // Length counters clock on steps 0, 2, 4, 6
71        if !self.frame_sequencer_step.bit(0) {
72            self.pulse_1.clock_length_counter();
73            self.pulse_2.clock_length_counter();
74            self.wavetable.clock_length_counter();
75            self.noise.clock_length_counter();
76        }
77
78        // Envelopes clock on step 7
79        if self.frame_sequencer_step == 7 {
80            self.pulse_1.clock_envelope();
81            self.pulse_2.clock_envelope();
82            self.noise.clock_envelope();
83        }
84
85        // Channel 1 sweep clocks on steps 2 and 6
86        if self.frame_sequencer_step == 2 || self.frame_sequencer_step == 6 {
87            self.pulse_1.clock_sweep();
88        }
89    }
90
91    pub fn sample(&self, channels_enabled: [bool; 4]) -> (i16, i16) {
92        let channels_enabled = channels_enabled.map(i16::from);
93
94        // On GBA, DAC-disabled channels behave as if they're outputting 0
95        let raw_samples = [
96            self.pulse_1.sample().unwrap_or(0),
97            self.pulse_2.sample().unwrap_or(0),
98            self.wavetable.sample(),
99            self.noise.sample().unwrap_or(0),
100        ]
101        .map(i16::from);
102
103        // To try and emulate the GBC's DACs, GBA biases each channel by its current volume
104        // Wavetable channel is always biased by -15 (tested on hardware)
105        let channel_bias =
106            [self.pulse_1.volume(), self.pulse_2.volume(), 15, self.noise.volume()].map(i16::from);
107
108        // Convert from unsigned 4-bit to signed 5-bit while applying bias
109        let samples: [i16; 4] =
110            array::from_fn(|i| channels_enabled[i] * (2 * raw_samples[i] - channel_bias[i]));
111
112        // Mix channels; result is signed 7-bit
113        let stereo_l = self.stereo_control.left_channels.map(i16::from);
114        let stereo_r = self.stereo_control.right_channels.map(i16::from);
115        let mut sample_l: i16 =
116            samples.into_iter().enumerate().map(|(i, sample)| stereo_l[i] * sample).sum();
117        let mut sample_r: i16 =
118            samples.into_iter().enumerate().map(|(i, sample)| stereo_r[i] * sample).sum();
119
120        // Apply master volume (1-8); result is signed 10-bit
121        sample_l *= i16::from(self.stereo_control.left_volume + 1);
122        sample_r *= i16::from(self.stereo_control.right_volume + 1);
123
124        debug_assert!((-0x200..0x200).contains(&sample_l));
125        debug_assert!((-0x200..0x200).contains(&sample_r));
126
127        (sample_l, sample_r)
128    }
129
130    pub fn disable(&mut self) {
131        *self = Self {
132            frame_sequencer_step: self.frame_sequencer_step,
133            frame_sequencer_divider: self.frame_sequencer_divider,
134            ..Self::new()
135        };
136    }
137
138    // $4000060: SOUND1CNT_L / NR10 (Channel 1 sweep)
139    pub fn write_sound1cnt_l(&mut self, value: u8) {
140        self.pulse_1.write_register_0(value);
141    }
142
143    // $4000060: SOUND1CNT_L / NR10 (Channel 1 sweep)
144    pub fn read_sound1cnt_l(&self) -> u8 {
145        self.pulse_1.read_register_0() & 0x7F
146    }
147
148    // $4000062: SOUND1CNT_H low / NR11 (Channel 1 duty cycle and length counter)
149    pub fn write_sound1cnt_h_low(&mut self, value: u8) {
150        self.pulse_1.write_register_1(value, true);
151    }
152
153    // $4000062: SOUND1CNT_H low / NR11 (Channel 1 duty cycle and length counter)
154    pub fn read_sound1cnt_h_low(&self) -> u8 {
155        self.pulse_1.read_register_1() & 0xC0
156    }
157
158    // $4000063: SOUND1CNT_H high / NR12 (Channel 1 envelope)
159    pub fn write_sound1cnt_h_high(&mut self, value: u8) {
160        self.pulse_1.write_register_2(value);
161    }
162
163    // $4000063: SOUND1CNT_H high / NR12 (Channel 1 envelope)
164    pub fn read_sound1cnt_h_high(&self) -> u8 {
165        self.pulse_1.read_register_2()
166    }
167
168    // $4000064: SOUND1CNT_X low / NR13 (Channel 1 frequency low bits)
169    pub fn write_sound1cnt_x_low(&mut self, value: u8) {
170        self.pulse_1.write_register_3(value);
171    }
172
173    // $4000065: SOUND1CNT_X high / NR14 (Channel 1 control)
174    pub fn write_sound1cnt_x_high(&mut self, value: u8) {
175        self.pulse_1.write_register_4(value, self.frame_sequencer_step);
176    }
177
178    // $4000065: SOUND1CNT_X high / NR14 (Channel 1 control)
179    pub fn read_sound1cnt_x_high(&self) -> u8 {
180        self.pulse_1.read_register_4() & 0x40
181    }
182
183    // $4000068: SOUND2CNT_L low / NR21 (Channel 2 duty cycle and length counter)
184    pub fn write_sound2cnt_l_low(&mut self, value: u8) {
185        self.pulse_2.write_register_1(value, true);
186    }
187
188    // $4000068: SOUND2CNT_L low / NR21 (Channel 2 duty cycle and length counter)
189    pub fn read_sound2cnt_l_low(&self) -> u8 {
190        self.pulse_2.read_register_1() & 0xC0
191    }
192
193    // $4000069: SOUND2CNT_L high / NR22 (Channel 2 envelope)
194    pub fn write_sound2cnt_l_high(&mut self, value: u8) {
195        self.pulse_2.write_register_2(value);
196    }
197
198    // $4000069: SOUND2CNT_L high / NR22 (Channel 2 envelope)
199    pub fn read_sound2cnt_l_high(&self) -> u8 {
200        self.pulse_2.read_register_2()
201    }
202
203    // $400006C: SOUND2CNT_H low / NR23 (Channel 2 frequency low bits)
204    pub fn write_sound2cnt_h_low(&mut self, value: u8) {
205        self.pulse_2.write_register_3(value);
206    }
207
208    // $400006D: SOUND2CNT_H high / NR24 (Channel 2 control)
209    pub fn write_sound2cnt_h_high(&mut self, value: u8) {
210        self.pulse_2.write_register_4(value, self.frame_sequencer_step);
211    }
212
213    // $400006D: SOUND2CNT_H high / NR24 (Channel 2 control)
214    pub fn read_sound2cnt_h_high(&self) -> u8 {
215        self.pulse_2.read_register_4() & 0x40
216    }
217
218    // $4000070: SOUND3CNT_L / NR30 (Channel 3 enabled and wave RAM control)
219    pub fn write_sound3cnt_l(&mut self, value: u8) {
220        self.wavetable.write_nr30(value);
221    }
222
223    // $4000070: SOUND3CNT_L / NR30 (Channel 3 enabled and wave RAM control)
224    pub fn read_sound3cnt_l(&self) -> u8 {
225        self.wavetable.read_nr30() & 0xE0
226    }
227
228    // $4000072: SOUND3CNT_H low / NR31 (Channel 3 length counter)
229    pub fn write_sound3cnt_h_low(&mut self, value: u8) {
230        self.wavetable.write_nr31(value);
231    }
232
233    // $4000073: SOUND3CNT_H high / NR32 (Channel 3 volume)
234    pub fn write_sound3cnt_h_high(&mut self, value: u8) {
235        self.wavetable.write_nr32(value);
236    }
237
238    // $4000073: SOUND3CNT_H high / NR32 (Channel 3 volume)
239    pub fn read_sound3cnt_h_high(&self) -> u8 {
240        self.wavetable.read_nr32() & 0xE0
241    }
242
243    // $4000074: SOUND3CNT_X low / NR33 (Channel 3 frequency low bits)
244    pub fn write_sound3cnt_x_low(&mut self, value: u8) {
245        self.wavetable.write_nr33(value);
246    }
247
248    // $4000075: SOUND3CNT_X high / NR34 (Channel 3 control)
249    pub fn write_sound3cnt_x_high(&mut self, value: u8) {
250        self.wavetable.write_nr34(value, self.frame_sequencer_step);
251    }
252
253    // $4000075: SOUND3CNT_X high / NR34 (Channel 3 control)
254    pub fn read_sound3cnt_x_high(&self) -> u8 {
255        self.wavetable.read_nr34() & 0x40
256    }
257
258    // $4000078: SOUND4CNT_L low / NR41 (Channel 4 length counter)
259    pub fn write_sound4cnt_l_low(&mut self, value: u8) {
260        self.noise.write_register_1(value);
261    }
262
263    // $4000079: SOUND4CNT_L high / NR42 (Channel 4 envelope)
264    pub fn write_sound4cnt_l_high(&mut self, value: u8) {
265        self.noise.write_register_2(value);
266    }
267
268    // $4000079: SOUND4CNT_L high / NR42 (Channel 4 envelope)
269    pub fn read_sound4cnt_l_high(&self) -> u8 {
270        self.noise.read_register_2()
271    }
272
273    // $400007C: SOUND4CNT_H low / NR43 (Channel 4 frequency)
274    pub fn write_sound4cnt_h_low(&mut self, value: u8) {
275        self.noise.write_register_3(value);
276    }
277
278    // $400007C: SOUND4CNT_H low / NR43 (Channel 4 frequency)
279    pub fn read_sound4cnt_h_low(&self) -> u8 {
280        self.noise.read_register_3()
281    }
282
283    // $400007D: SOUND4CNT_H high / NR44 (Channel 4 control)
284    pub fn write_sound4cnt_h_high(&mut self, value: u8) {
285        self.noise.write_register_4(value, self.frame_sequencer_step);
286    }
287
288    // $400007D: SOUND4CNT_H high / NR44 (Channel 4 control)
289    pub fn read_sound4cnt_h_high(&self) -> u8 {
290        self.noise.read_register_4() & 0x40
291    }
292
293    // $4000080: SOUNDCNT_L low / NR50 (PSG master volume)
294    pub fn write_soundcnt_l_low(&mut self, value: u8) {
295        self.stereo_control.write_volume(value);
296    }
297
298    // $4000080: SOUNDCNT_L low / NR50 (PSG master volume)
299    pub fn read_soundcnt_l_low(&self) -> u8 {
300        self.stereo_control.read_volume() & 0x77
301    }
302
303    // $4000081: SOUNDCNT_L high / NR51 (PSG stereo control)
304    pub fn write_soundcnt_l_high(&mut self, value: u8) {
305        self.stereo_control.write_enabled(value);
306    }
307
308    // $4000081: SOUNDCNT_L high / NR51 (PSG stereo control)
309    pub fn read_soundcnt_l_high(&self) -> u8 {
310        self.stereo_control.read_enabled()
311    }
312
313    // $4000084: SOUNDCNT_X / NR52 (Channels and APU enabled)
314    pub fn read_soundcnt_x(&self, apu_enabled: bool) -> u8 {
315        (u8::from(self.pulse_1.enabled()))
316            | (u8::from(self.pulse_2.enabled()) << 1)
317            | (u8::from(self.wavetable.active()) << 2)
318            | (u8::from(self.noise.enabled()) << 3)
319            | (u8::from(apu_enabled) << 7)
320    }
321
322    // $4000090-$400009F: Wave RAM
323    pub fn read_wave_ram(&self, address: u32) -> u8 {
324        self.wavetable.read_wave_ram(address)
325    }
326
327    // $4000090-$400009F: Wave RAM
328    pub fn write_wave_ram(&mut self, address: u32, value: u8) {
329        self.wavetable.write_wave_ram(address, value);
330    }
331}