aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2017-11-30 19:38:11 -0500
committerDeterminant <ted.sybil@gmail.com>2017-11-30 19:38:11 -0500
commitc1961037e6e45c4f7fb91c9fde64364e3b3f5e7d (patch)
treea0c16a4eea70519569cf614bc785ac2e7c5de6a2
parent458f019cb2e89e3f0947acfff9f65bbd90d2cfd1 (diff)
...
-rw-r--r--src/apu.rs41
-rw-r--r--src/bin.rs46
2 files changed, 37 insertions, 50 deletions
diff --git a/src/apu.rs b/src/apu.rs
index 5d264fb..3ca81aa 100644
--- a/src/apu.rs
+++ b/src/apu.rs
@@ -150,13 +150,12 @@ pub struct Pulse {
impl Pulse {
fn tick_env(&mut self) {
- /* should be clocked by frame counter */
if !self.env_start {
if self.env_lvl == 0 {
self.env_lvl = self.env_period;
if self.decay_lvl == 0 {
if self.env_loop {
- self.decay_lvl = 15;
+ self.decay_lvl = 0xf;
}
} else {
self.decay_lvl -= 1;
@@ -165,7 +164,7 @@ impl Pulse {
self.env_lvl -= 1;
}
} else {
- self.decay_lvl = 15;
+ self.decay_lvl = 0xf;
self.env_start = false;
self.env_lvl = self.env_period;
}
@@ -176,7 +175,7 @@ impl Pulse {
if self.swp_lvl == 0 {
reload = true;
if self.swp_en {
- let mut p = self.timer_period;
+ let mut p: u16 = self.timer_period;
let mut delta = p >> self.swp_count;
if self.swp_neg {
delta = !delta;
@@ -254,18 +253,19 @@ impl Pulse {
self.set_const(data & 0x10 == 0x10);
self.set_env_period(data & 0xf);
self.set_env_vol(data & 0xf);
- self.env_start = true;
}
pub fn write_reg2(&mut self, data: u8) { self.set_sweep(data) }
pub fn write_reg3(&mut self, data: u8) {
- self.timer_period = (self.timer_period & 0xff00) | data as u16
+ let p = (self.timer_period & 0xff00) | data as u16;
+ self.set_timer_period(p);
}
pub fn write_reg4(&mut self, data: u8) {
self.set_len(data >> 3);
- self.timer_period = (self.timer_period & 0x00ff) | ((data as u16 & 7) << 8);
+ let p = (self.timer_period & 0x00ff) | ((data as u16 & 7) << 8);
+ self.set_timer_period(p);
self.seq_cnt = 0;
self.env_start = true;
}
@@ -358,7 +358,6 @@ impl Triangle {
fn set_cnt_lvl(&mut self, d: u8) { self.cnt_lvl = d }
fn set_ctrl(&mut self, b: bool) { self.ctrl = b }
fn set_cnt_rld_val(&mut self, d: u8) { self.cnt_rld_val = d }
- fn set_timer_peroid(&mut self, p: u16) { self.timer_period = p }
fn set_len(&mut self, d: u8) {
if self.enabled {
self.len_lvl = LEN_TABLE[d as usize]
@@ -371,22 +370,17 @@ impl Triangle {
}
pub fn write_reg3(&mut self, data: u8) {
- self.timer_period = (self.timer_period & 0xff00) | data as u16
+ self.timer_period = (self.timer_period & 0xff00) | data as u16;
}
pub fn write_reg4(&mut self, data: u8) {
self.set_len(data >> 3);
self.timer_period = (self.timer_period & 0x00ff) | ((data as u16 & 7) << 8);
- self.seq_cnt = 0;
self.timer_lvl = self.timer_period;
self.cnt_rld = true;
}
- fn output(&self) -> u8 {
- let len = self.len_lvl > 0;
- let lin = self.cnt_lvl > 0;
- if len && lin { TRI_SEQ_TABLE[self.seq_cnt as usize] } else { 0 }
- }
+ fn output(&self) -> u8 { TRI_SEQ_TABLE[self.seq_cnt as usize] }
}
pub struct APU<'a> {
@@ -466,6 +460,9 @@ impl<'a> APU<'a> {
pub fn write_frame_counter(&mut self, data: u8) {
self.frame_inh = data & 0x40 == 1;
self.frame_mode = data >> 7 == 1;
+ if self.frame_mode {
+ self.tick_len_swp()
+ }
}
fn tick_timer(&mut self) {
@@ -480,9 +477,10 @@ impl<'a> APU<'a> {
let f = self.frame_lvl;
match self.frame_mode {
false => {
+ self.frame_lvl = if f == 3 { 0 } else { f + 1 };
match f {
- 0 | 2 => self.tick_env(),
- 1 => {
+ 1 | 3 => self.tick_env(),
+ 2 => {
self.tick_env();
self.tick_len_swp();
},
@@ -494,18 +492,17 @@ impl<'a> APU<'a> {
}
},
};
- self.frame_lvl = if f == 3 { 0 } else { f + 1 }
},
true => {
+ self.frame_lvl = if f == 4 { 0 } else { f + 1 };
match f {
- 0 | 2 => self.tick_env(),
- 1 | 4 => {
+ 1 | 3 => self.tick_env(),
+ 0 | 2 => {
self.tick_env();
self.tick_len_swp();
},
- _ => ()
+ _ => self.tick_env()
}
- self.frame_lvl = if f == 4 { 0 } else { f + 1 }
}
}
self.frame_int
diff --git a/src/bin.rs b/src/bin.rs
index caa3658..faf6962 100644
--- a/src/bin.rs
+++ b/src/bin.rs
@@ -32,7 +32,7 @@ use memory::{CPUMemory, PPUMemory, VMem};
use cartridge::{BankType, MirrorType, Cartridge};
use controller::stdctl;
-const PIXEL_SIZE: u32 = 2;
+const PIXEL_SIZE: u32 = 3;
const RGB_COLORS: [u32; 64] = [
0x666666, 0x002a88, 0x1412a7, 0x3b00a4, 0x5c007e, 0x6e0040, 0x6c0600, 0x561d00,
0x333500, 0x0b4800, 0x005200, 0x004f08, 0x00404d, 0x000000, 0x000000, 0x000000,
@@ -227,10 +227,8 @@ impl<'a> ppu::Screen for SDLWindow<'a> {
}
}
-struct SDLAudio {
- device: sdl2::audio::AudioQueue<i16>,
- buffer: [i16; 1],
- buffer_cnt: usize
+struct SDLAudio<'a> {
+ device: &'a sdl2::audio::AudioQueue<i16>,
}
/*
@@ -255,39 +253,22 @@ fn gen_wave(bytes_to_write: i32) -> Vec<i16> {
}
*/
-impl SDLAudio {
- fn new(sdl_context: &sdl2::Sdl) -> Self {
- let audio_subsystem = sdl_context.audio().unwrap();
- let desired_spec = AudioSpecDesired {
- freq: Some(apu::AUDIO_SAMPLE_FREQ as i32),
- channels: Some(1),
- samples: Some(4096)
- };
- let device = audio_subsystem.open_queue::<i16, _>(None, &desired_spec).unwrap();
+impl<'a> SDLAudio<'a> {
+ fn new(device: &'a sdl2::audio::AudioQueue<i16>) -> Self {
let t = SDLAudio {
- device, buffer: [0; 1], buffer_cnt: 0
+ device
};
t.device.resume();
t
}
-
- fn flush(&mut self) {
- self.device.queue(&self.buffer[..self.buffer_cnt]);
- self.buffer_cnt = 0;
- }
}
-impl apu::Speaker for SDLAudio {
+impl<'a> apu::Speaker for SDLAudio<'a> {
fn queue(&mut self, sample: u16) {
- self.buffer[self.buffer_cnt] = sample.wrapping_sub(32768) as i16;
- self.buffer_cnt += 1;
- if self.buffer_cnt == self.buffer.len() {
- self.flush()
- }
+ self.device.queue(&[sample.wrapping_sub(32768) as i16]);
}
fn push(&mut self) {
- self.flush();
}
}
@@ -360,11 +341,20 @@ fn main() {
}
}
*/
+
let sdl_context = sdl2::init().unwrap();
+ let audio_subsystem = sdl_context.audio().unwrap();
+ let desired_spec = AudioSpecDesired {
+ freq: Some(apu::AUDIO_SAMPLE_FREQ as i32),
+ channels: Some(1),
+ samples: Some(4096)
+ };
+ let device = audio_subsystem.open_queue::<i16, _>(None, &desired_spec).unwrap();
+
let p1ctl = stdctl::Joystick::new();
let cart = SimpleCart::new(chr_rom, prg_rom, sram, mirror);
let mut win = SDLWindow::new(&sdl_context, &p1ctl);
- let mut spkr = SDLAudio::new(&sdl_context);
+ let mut spkr = SDLAudio::new(&device);
let mut m: Box<mapper::Mapper> = match mapper_id {
0 | 2 => Box::new(mapper::Mapper2::new(cart)),
1 => Box::new(mapper::Mapper1::new(cart)),