2019-12-17 04:06:00 +00:00
|
|
|
const duty_cycle_sequences: [[u8; 8]; 4] = [
|
|
|
|
[0, 1, 0, 0, 0, 0, 0, 0],
|
|
|
|
[0, 1, 1, 0, 0, 0, 0, 0],
|
|
|
|
[0, 1, 1, 1, 1, 0, 0, 0],
|
|
|
|
[1, 0, 0, 1, 1, 1, 1, 1],
|
|
|
|
];
|
|
|
|
|
|
|
|
pub struct Square {
|
|
|
|
pub sample: u16,
|
|
|
|
duty_cycle: [u8; 8],
|
|
|
|
duty_counter: u8,
|
|
|
|
length_counter_halt: bool, // (this bit is also the envelope's loop flag)
|
|
|
|
constant_volume_flag: bool, // (0: use volume from envelope; 1: use constant volume)
|
|
|
|
timer: usize,
|
|
|
|
pub length_counter: usize,
|
|
|
|
envelope: usize,
|
|
|
|
sweep: usize,
|
|
|
|
pub enabled: bool,
|
2019-12-17 05:43:10 +00:00
|
|
|
decay_counter: u8,
|
|
|
|
start: bool,
|
|
|
|
divider: usize,
|
2019-12-17 04:06:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Square {
|
2019-11-27 01:11:51 +00:00
|
|
|
pub fn new() -> Self {
|
2019-12-17 04:06:00 +00:00
|
|
|
Square {
|
|
|
|
duty_cycle: duty_cycle_sequences[0],
|
|
|
|
duty_counter: 0,
|
2019-11-27 01:11:51 +00:00
|
|
|
length_counter_halt: false,
|
|
|
|
constant_volume_flag: false,
|
|
|
|
timer: 0,
|
|
|
|
length_counter: 0,
|
|
|
|
envelope: 0,
|
|
|
|
sweep: 0,
|
2019-12-05 02:57:05 +00:00
|
|
|
sample: 0,
|
2019-12-15 00:15:06 +00:00
|
|
|
enabled: false,
|
2019-12-17 05:43:10 +00:00
|
|
|
decay_counter: 0,
|
|
|
|
start: false,
|
|
|
|
divider: 0,
|
2019-11-27 01:11:51 +00:00
|
|
|
}
|
|
|
|
}
|
2019-12-05 02:57:05 +00:00
|
|
|
|
|
|
|
pub fn clock(&mut self) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-12-17 05:43:10 +00:00
|
|
|
pub fn clock_frame_counter(&mut self) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn clock_envelope(&mut self) {
|
|
|
|
if self.start {
|
|
|
|
self.envelope -= 1;
|
|
|
|
self.start = false;
|
|
|
|
} else {
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// $4000/$4004
|
2019-12-05 02:57:05 +00:00
|
|
|
pub fn duty(&mut self, value: u8) {
|
2019-12-17 04:06:00 +00:00
|
|
|
self.duty_cycle = duty_cycle_sequences[(value >> 6) as usize];
|
|
|
|
self.length_counter_halt = value & (1<<5) != 0;
|
|
|
|
self.constant_volume_flag = value & (1<<4) != 0;
|
2019-12-17 05:43:10 +00:00
|
|
|
if self.constant_volume_flag {
|
|
|
|
self.envelope = value & 0b1111;
|
|
|
|
} else {
|
|
|
|
self.envelope = self.decay_counter;
|
|
|
|
}
|
2019-12-05 02:57:05 +00:00
|
|
|
}
|
|
|
|
|
2019-12-17 05:43:10 +00:00
|
|
|
// $4001/$4005
|
2019-12-05 02:57:05 +00:00
|
|
|
pub fn sweep(&mut self, value: u8) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-12-17 05:43:10 +00:00
|
|
|
// $4002/$4006
|
2019-12-05 02:57:05 +00:00
|
|
|
pub fn timer_low(&mut self, value: u8) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-12-17 05:43:10 +00:00
|
|
|
// $4003/$4007
|
2019-12-05 02:57:05 +00:00
|
|
|
pub fn timer_high(&mut self, value: u8) {
|
|
|
|
|
|
|
|
}
|
2019-12-10 03:22:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct EnvelopeGenerator {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
struct SweepUnit {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Timer {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Sequencer {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
struct LengthCounter {
|
|
|
|
|
|
|
|
}
|