1#![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))]
7
8use bit_field::BitField;
9
10use super::data;
11use super::ChipModel;
12
13const ACC_MASK: u32 = 0x00ff_ffff;
14const ACC_BIT19_MASK: u32 = 0x0008_0000;
15const ACC_MSB_MASK: u32 = 0x0080_0000;
16const SHIFT_MASK: u32 = 0x007f_ffff;
17const OUTPUT_MASK: u16 = 0x0fff;
18
19#[derive(Clone, Copy)]
26pub struct WaveformGenerator {
27 frequency: u16,
29 pulse_width: u16,
30 waveform: u8,
32 ring: bool,
33 sync: bool,
34 test: bool,
35 pub acc: u32,
37 pub shift: u32,
38 msb_rising: bool,
39 wave_ps: &'static [u8; 4096],
41 wave_pst: &'static [u8; 4096],
42 wave_pt: &'static [u8; 4096],
43 wave_st: &'static [u8; 4096],
44}
45
46pub struct Syncable<T> {
47 pub main: T,
48 pub sync_source: T,
49 pub sync_dest: T,
50}
51
52impl WaveformGenerator {
53 pub fn new(chip_model: ChipModel) -> Self {
54 let (wave_ps, wave_pst, wave_pt, wave_st) = match chip_model {
55 ChipModel::Mos6581 => (
56 &data::WAVE6581_PS,
57 &data::WAVE6581_PST,
58 &data::WAVE6581_PT,
59 &data::WAVE6581_ST,
60 ),
61 ChipModel::Mos8580 => (
62 &data::WAVE8580_PS,
63 &data::WAVE8580_PST,
64 &data::WAVE8580_PT,
65 &data::WAVE8580_ST,
66 ),
67 };
68 let mut waveform = WaveformGenerator {
69 frequency: 0,
70 pulse_width: 0,
71 waveform: 0,
72 ring: false,
73 sync: false,
74 test: false,
75 acc: 0,
76 shift: 0,
77 msb_rising: false,
78 wave_ps,
79 wave_pst,
80 wave_pt,
81 wave_st,
82 };
83 waveform.reset();
84 waveform
85 }
86
87 pub fn get_acc(&self) -> u32 {
88 self.acc
89 }
90
91 pub fn get_control(&self) -> u8 {
92 let mut value = 0u8;
93 value.set_bit(1, self.sync);
94 value.set_bit(2, self.ring);
95 value.set_bit(3, self.test);
96 value | (self.waveform << 4)
97 }
98
99 pub fn get_frequency(&self) -> u16 {
100 self.frequency
101 }
102
103 pub fn get_frequency_hi(&self) -> u8 {
104 (self.frequency >> 8) as u8
105 }
106
107 pub fn get_frequency_lo(&self) -> u8 {
108 (self.frequency & 0x00ff) as u8
109 }
110
111 pub fn get_pulse_width_hi(&self) -> u8 {
112 (self.pulse_width >> 8) as u8
113 }
114
115 pub fn get_pulse_width_lo(&self) -> u8 {
116 (self.pulse_width & 0x00ff) as u8
117 }
118
119 pub fn get_shift(&self) -> u32 {
120 self.shift
121 }
122
123 pub fn get_sync(&self) -> bool {
124 self.sync
125 }
126
127 pub fn is_msb_rising(&self) -> bool {
128 self.msb_rising
129 }
130
131 pub fn set_acc(&mut self, value: u32) {
132 self.acc = value;
133 }
134
135 pub fn set_control(&mut self, value: u8) {
136 self.waveform = (value >> 4) & 0x0f;
137 self.sync = value.get_bit(1);
138 self.ring = value.get_bit(2);
139 let test = value.get_bit(3);
140 if test {
141 self.acc = 0;
150 self.shift = 0;
151 } else if self.test {
152 self.shift = 0x007f_fff8;
159 }
160 self.test = test;
161 }
162
163 pub fn set_frequency_hi(&mut self, value: u8) {
164 let result = (((value as u16) << 8) & 0xff00) | (self.frequency & 0x00ff);
165 self.frequency = result;
166 }
167
168 pub fn set_frequency_lo(&mut self, value: u8) {
169 let result = (self.frequency & 0xff00) | ((value as u16) & 0x00ff);
170 self.frequency = result;
171 }
172
173 pub fn set_pulse_width_hi(&mut self, value: u8) {
174 let result = (((value as u16) << 8) & 0x0f00) | (self.pulse_width & 0x00ff);
175 self.pulse_width = result;
176 }
177
178 pub fn set_pulse_width_lo(&mut self, value: u8) {
179 let result = (self.pulse_width & 0x0f00) | ((value as u16) & 0x00ff);
180 self.pulse_width = result;
181 }
182
183 #[inline]
184 pub fn clock(&mut self) {
185 if !self.test {
187 let acc_prev = self.acc;
188 self.acc = (self.acc + self.frequency as u32) & ACC_MASK;
190 self.msb_rising = (acc_prev & ACC_MSB_MASK) == 0 && (self.acc & ACC_MSB_MASK) != 0;
192 if (acc_prev & ACC_BIT19_MASK) == 0 && (self.acc & ACC_BIT19_MASK) != 0 {
193 let bit0 = ((self.shift >> 22) ^ (self.shift >> 17)) & 0x01;
195 self.shift = ((self.shift << 1) & SHIFT_MASK) | bit0;
196 }
197 }
198 }
199
200 #[inline]
201 pub fn clock_delta(&mut self, delta: u32) {
202 if !self.test {
203 let acc_prev = self.acc;
204 let mut delta_acc = delta * self.frequency as u32;
206 self.acc = (self.acc + delta_acc) & ACC_MASK;
207 self.msb_rising = (acc_prev & ACC_MSB_MASK) == 0 && (self.acc & ACC_MSB_MASK) != 0;
209 let mut shift_period = 0x0010_0000;
212 while delta_acc != 0 {
213 if delta_acc < shift_period {
214 shift_period = delta_acc;
215 if shift_period <= 0x0008_0000 {
218 if ((self.acc as i32 - shift_period as i32) & ACC_BIT19_MASK as i32) != 0
220 || (self.acc & ACC_BIT19_MASK) == 0
221 {
222 break;
223 }
224 } else if ((self.acc as i32 - shift_period as i32) & ACC_BIT19_MASK as i32) != 0
226 && (self.acc & ACC_BIT19_MASK) == 0
227 {
228 break;
229 }
230 }
231 let bit0 = ((self.shift >> 22) ^ (self.shift >> 17)) & 0x01;
233 self.shift = (self.shift << 1) & SHIFT_MASK | bit0;
234 delta_acc -= shift_period;
235 }
236 }
237 }
238
239 #[inline]
241 pub fn output(&self, sync_source: Option<&WaveformGenerator>) -> u16 {
242 match self.waveform {
243 0x0 => 0,
244 0x1 => self.output_t(sync_source),
245 0x2 => self.output_s(),
246 0x3 => self.output_st(),
247 0x4 => self.output_p(),
248 0x5 => self.output_pt(sync_source),
249 0x6 => self.output_ps(),
250 0x7 => self.output_pst(),
251 0x8 => self.output_n(),
252 0x9 => 0,
253 0xa => 0,
254 0xb => 0,
255 0xc => 0,
256 0xd => 0,
257 0xe => 0,
258 0xf => 0,
259 _ => panic!("invalid waveform {}", self.waveform),
260 }
261 }
262
263 pub fn reset(&mut self) {
264 self.frequency = 0;
265 self.pulse_width = 0;
266 self.waveform = 0; self.ring = false;
268 self.sync = false;
269 self.test = false;
270 self.acc = 0;
271 self.shift = 0x007f_fff8;
272 self.msb_rising = false;
273 }
274
275 #[inline]
296 fn output_n(&self) -> u16 {
297 (((self.shift & 0x0040_0000) >> 11)
298 | ((self.shift & 0x0010_0000) >> 10)
299 | ((self.shift & 0x0001_0000) >> 7)
300 | ((self.shift & 0x0000_2000) >> 5)
301 | ((self.shift & 0x0000_0800) >> 4)
302 | ((self.shift & 0x0000_0080) >> 1)
303 | ((self.shift & 0x0000_0010) << 1)
304 | ((self.shift & 0x0000_0004) << 2)) as u16
305 }
306
307 #[inline]
317 fn output_p(&self) -> u16 {
318 if self.test || ((self.acc >> 12) as u16 >= self.pulse_width) {
319 0x0fff
320 } else {
321 0x0000
322 }
323 }
324
325 #[inline]
328 fn output_s(&self) -> u16 {
329 (self.acc >> 12) as u16
330 }
331
332 #[inline]
339 fn output_t(&self, sync_source: Option<&WaveformGenerator>) -> u16 {
340 let acc = if self.ring {
341 self.acc ^ sync_source.map(|x| x.acc).unwrap_or(0)
342 } else {
343 self.acc
344 };
345 let msb = acc & ACC_MSB_MASK;
346 let output = if msb != 0 { !self.acc } else { self.acc };
347 (output >> 11) as u16 & OUTPUT_MASK
348 }
349
350 #[inline]
353 fn output_ps(&self) -> u16 {
354 ((self.wave_ps[self.output_s() as usize] as u16) << 4) & self.output_p()
355 }
356
357 #[inline]
358 fn output_pst(&self) -> u16 {
359 ((self.wave_pst[self.output_s() as usize] as u16) << 4) & self.output_p()
360 }
361
362 #[inline]
363 fn output_pt(&self, sync_source: Option<&WaveformGenerator>) -> u16 {
364 ((self.wave_pt[(self.output_t(sync_source) >> 1) as usize] as u16) << 4) & self.output_p()
365 }
366
367 #[inline]
368 fn output_st(&self) -> u16 {
369 (self.wave_st[self.output_s() as usize] as u16) << 4
370 }
371}
372
373impl Syncable<&'_ WaveformGenerator> {
374 pub fn read_osc(&self) -> u8 {
375 (self.main.output(Some(self.sync_source)) >> 4) as u8
376 }
377}
378
379impl Syncable<&'_ mut WaveformGenerator> {
380 #[inline]
386 pub fn synchronize(&mut self) {
387 if self.main.is_msb_rising() {
391 if self.sync_dest.sync {
392 if !(self.main.sync && self.sync_source.is_msb_rising()) {
393 self.sync_dest.set_acc(0);
394 }
395 }
396 }
397 }
398}