apu
This commit is contained in:
parent
1c19b9d10a
commit
8a8d45cbff
|
@ -1,6 +1,14 @@
|
|||
impl super::DMC {
|
||||
pub struct DMC {
|
||||
pub sample: u16,
|
||||
pub enabled: bool,
|
||||
pub interrupt: bool,
|
||||
pub length_counter: usize,
|
||||
pub bytes_remaining: usize,
|
||||
}
|
||||
|
||||
impl DMC {
|
||||
pub fn new() -> Self {
|
||||
super::DMC {
|
||||
DMC {
|
||||
sample: 0,
|
||||
enabled: false,
|
||||
bytes_remaining: 0,
|
||||
|
|
|
@ -3,6 +3,11 @@ mod square;
|
|||
mod triangle;
|
||||
mod dmc;
|
||||
|
||||
use noise::Noise;
|
||||
use square::Square;
|
||||
use triangle::Triangle;
|
||||
use dmc::DMC;
|
||||
|
||||
// APU clock ticks every other CPU cycle.
|
||||
// Frame counter only ticks every 3728.5 APU ticks, and in audio frames of 4 or 5.
|
||||
// Length counter controls note durations.
|
||||
|
@ -33,48 +38,6 @@ pub struct Apu {
|
|||
frame_interrupt: bool,
|
||||
}
|
||||
|
||||
struct Square {
|
||||
sample: u16,
|
||||
duty_cycle: 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,
|
||||
length_counter: usize,
|
||||
envelope: usize,
|
||||
sweep: usize,
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
// $4008 Hlll.llll Triangle channel length counter halt and linear counter load (write)
|
||||
// bit 7 H--- ---- Halt length counter (this bit is also the linear counter's control flag)
|
||||
struct Triangle {
|
||||
sample: u16,
|
||||
timer: usize,
|
||||
length_counter: usize, // (this bit is also the linear counter's control flag)
|
||||
linear_counter: usize,
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
// $400E M---.PPPP Mode and period (write)
|
||||
// bit 7 M--- ---- Mode flag
|
||||
struct Noise {
|
||||
sample: u16,
|
||||
timer: usize,
|
||||
length_counter: usize,
|
||||
envelope: usize,
|
||||
linear_feedback_sr: u16,
|
||||
mode: bool, // also called loop noise, bit 7 of $400E
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
struct DMC {
|
||||
sample: u16,
|
||||
enabled: bool,
|
||||
interrupt: bool,
|
||||
length_counter: usize,
|
||||
bytes_remaining: usize,
|
||||
}
|
||||
|
||||
struct Envelope {
|
||||
start_flag: bool,
|
||||
divider: usize,
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
impl super::Noise {
|
||||
|
||||
// $400E M---.PPPP Mode and period (write)
|
||||
// bit 7 M--- ---- Mode flag
|
||||
pub struct Noise {
|
||||
pub sample: u16,
|
||||
timer: usize,
|
||||
pub length_counter: usize,
|
||||
envelope: usize,
|
||||
linear_feedback_sr: u16,
|
||||
mode: bool, // also called loop noise, bit 7 of $400E
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
impl Noise {
|
||||
pub fn new() -> Self {
|
||||
super::Noise {
|
||||
Noise {
|
||||
timer: 0,
|
||||
length_counter: 0,
|
||||
envelope: 0,
|
||||
|
|
|
@ -1,7 +1,28 @@
|
|||
impl super::Square {
|
||||
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,
|
||||
}
|
||||
|
||||
impl Square {
|
||||
pub fn new() -> Self {
|
||||
super::Square {
|
||||
duty_cycle: 0,
|
||||
Square {
|
||||
duty_cycle: duty_cycle_sequences[0],
|
||||
duty_counter: 0,
|
||||
length_counter_halt: false,
|
||||
constant_volume_flag: false,
|
||||
timer: 0,
|
||||
|
@ -18,8 +39,10 @@ impl super::Square {
|
|||
}
|
||||
|
||||
pub fn duty(&mut self, value: u8) {
|
||||
self.duty_cycle = value >> 6;
|
||||
// self.length_counter_halt =
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
pub fn sweep(&mut self, value: u8) {
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
impl super::Triangle {
|
||||
|
||||
// $4008 Hlll.llll Triangle channel length counter halt and linear counter load (write)
|
||||
// bit 7 H--- ---- Halt length counter (this bit is also the linear counter's control flag)
|
||||
pub struct Triangle {
|
||||
pub sample: u16,
|
||||
timer: usize,
|
||||
pub length_counter: usize, // (this bit is also the linear counter's control flag)
|
||||
linear_counter: usize,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
impl Triangle {
|
||||
pub fn new() -> Self {
|
||||
super::Triangle {
|
||||
Triangle {
|
||||
timer: 0,
|
||||
length_counter: 0,
|
||||
linear_counter: 0,
|
||||
|
|
Loading…
Reference in New Issue