Update to v082r03 release.

byuu says:

Couple more fixes to audio from Jonas, and I converted all types from
"unsigned" to the smallest sizes possible, which simplified a bit of the
code. Love variable-length integers.

Audio core should be really good now. Not perfect, but pretty close for
99% of games. Also fixed the window stuff for Cool World and such.
This commit is contained in:
Tim Allen
2011-09-05 13:56:22 +10:00
parent a86c5ee59d
commit 496708cffe
15 changed files with 64 additions and 64 deletions

View File

@@ -3,7 +3,7 @@ include nall/Makefile
snes := snes snes := snes
gameboy := gameboy gameboy := gameboy
profile := accuracy profile := accuracy
ui := ui ui := ui-gameboy
# options += console # options += console
# options += debugger # options += debugger

View File

@@ -1,8 +1,8 @@
struct Master { struct Master {
bool left_in_enable; bool left_in_enable;
unsigned left_volume; uint3 left_volume;
bool right_in_enable; bool right_in_enable;
unsigned right_volume; uint3 right_volume;
bool channel4_left_enable; bool channel4_left_enable;
bool channel3_left_enable; bool channel3_left_enable;
bool channel2_left_enable; bool channel2_left_enable;

View File

@@ -13,7 +13,7 @@ void APU::Noise::run() {
} }
} }
uint4 sample = (lfsr & 1) ? 0 : volume; uint4 sample = (lfsr & 1) ? (uint4)0 : volume;
if(enable == false) sample = 0; if(enable == false) sample = 0;
output = (sample * 4369) - 32768; output = (sample * 4369) - 32768;
@@ -26,9 +26,8 @@ void APU::Noise::clock_length() {
} }
void APU::Noise::clock_envelope() { void APU::Noise::clock_envelope() {
if(envelope_period && --envelope_period == 0) { if(enable && envelope_frequency && --envelope_period == 0) {
envelope_period = envelope_frequency; envelope_period = envelope_frequency;
if(envelope_period == 0) envelope_period = 8;
if(envelope_direction == 0 && volume > 0) volume--; if(envelope_direction == 0 && volume > 0) volume--;
if(envelope_direction == 1 && volume < 15) volume++; if(envelope_direction == 1 && volume < 15) volume++;
} }

View File

@@ -1,18 +1,18 @@
struct Noise { struct Noise {
bool enable; bool enable;
unsigned envelope_volume; uint4 envelope_volume;
bool envelope_direction; bool envelope_direction;
unsigned envelope_frequency; uint3 envelope_frequency;
unsigned frequency; uint4 frequency;
bool narrow_lfsr; bool narrow_lfsr;
unsigned divisor; unsigned divisor;
bool counter; bool counter;
int16 output; int16 output;
unsigned length; unsigned length;
unsigned envelope_period; uint3 envelope_period;
unsigned volume; uint4 volume;
unsigned period; unsigned period;
uint15 lfsr; uint15 lfsr;

View File

@@ -7,7 +7,7 @@ bool APU::Square1::dac_enable() {
void APU::Square1::run() { void APU::Square1::run() {
if(period && --period == 0) { if(period && --period == 0) {
period = 4 * (2048 - frequency); period = 4 * (2048 - frequency);
phase = (phase + 1) & 7; phase++;
switch(duty) { switch(duty) {
case 0: duty_output = (phase == 6); break; //______-_ case 0: duty_output = (phase == 6); break; //______-_
case 1: duty_output = (phase >= 6); break; //______-- case 1: duty_output = (phase >= 6); break; //______--
@@ -16,7 +16,7 @@ void APU::Square1::run() {
} }
} }
uint4 sample = (duty_output ? volume : 0); uint4 sample = (duty_output ? volume : (uint4)0);
if(enable == false) sample = 0; if(enable == false) sample = 0;
output = (sample * 4369) - 32768; output = (sample * 4369) - 32768;
@@ -45,20 +45,16 @@ void APU::Square1::clock_length() {
} }
void APU::Square1::clock_sweep() { void APU::Square1::clock_sweep() {
if(enable && --sweep_period == 0) { if(enable && sweep_frequency && --sweep_period == 0) {
sweep_period = sweep_frequency; sweep_period = sweep_frequency;
if(sweep_period == 0) sweep_period = 8; sweep(1);
if(sweep_frequency) { sweep(0);
sweep(1);
sweep(0);
}
} }
} }
void APU::Square1::clock_envelope() { void APU::Square1::clock_envelope() {
if(envelope_period && --envelope_period == 0) { if(enable && envelope_frequency && --envelope_period == 0) {
envelope_period = envelope_frequency; envelope_period = envelope_frequency;
if(envelope_period == 0) envelope_period = 8;
if(envelope_direction == 0 && volume > 0) volume--; if(envelope_direction == 0 && volume > 0) volume--;
if(envelope_direction == 1 && volume < 15) volume++; if(envelope_direction == 1 && volume < 15) volume++;
} }

View File

@@ -1,27 +1,27 @@
struct Square1 { struct Square1 {
bool enable; bool enable;
unsigned sweep_frequency; uint3 sweep_frequency;
unsigned sweep_direction; bool sweep_direction;
unsigned sweep_shift; uint3 sweep_shift;
bool sweep_negate; bool sweep_negate;
unsigned duty; uint2 duty;
unsigned length; unsigned length;
unsigned envelope_volume; uint4 envelope_volume;
unsigned envelope_direction; bool envelope_direction;
unsigned envelope_frequency; uint3 envelope_frequency;
unsigned frequency; uint11 frequency;
unsigned counter; bool counter;
int16 output; int16 output;
bool duty_output; bool duty_output;
unsigned phase; uint3 phase;
unsigned period; unsigned period;
unsigned envelope_period; uint3 envelope_period;
unsigned sweep_period; uint3 sweep_period;
signed frequency_shadow; signed frequency_shadow;
bool sweep_enable; bool sweep_enable;
unsigned volume; uint4 volume;
bool dac_enable(); bool dac_enable();

View File

@@ -7,7 +7,7 @@ bool APU::Square2::dac_enable() {
void APU::Square2::run() { void APU::Square2::run() {
if(period && --period == 0) { if(period && --period == 0) {
period = 4 * (2048 - frequency); period = 4 * (2048 - frequency);
phase = (phase + 1) & 7; phase++;
switch(duty) { switch(duty) {
case 0: duty_output = (phase == 6); break; //______-_ case 0: duty_output = (phase == 6); break; //______-_
case 1: duty_output = (phase >= 6); break; //______-- case 1: duty_output = (phase >= 6); break; //______--
@@ -16,7 +16,7 @@ void APU::Square2::run() {
} }
} }
uint4 sample = (duty_output ? volume : 0); uint4 sample = (duty_output ? volume : (uint4)0);
if(enable == false) sample = 0; if(enable == false) sample = 0;
output = (sample * 4369) - 32768; output = (sample * 4369) - 32768;
@@ -29,9 +29,8 @@ void APU::Square2::clock_length() {
} }
void APU::Square2::clock_envelope() { void APU::Square2::clock_envelope() {
if(envelope_period && --envelope_period == 0) { if(enable && envelope_frequency && --envelope_period == 0) {
envelope_period = envelope_frequency; envelope_period = envelope_frequency;
if(envelope_period == 0) envelope_period = 8;
if(envelope_direction == 0 && volume > 0) volume--; if(envelope_direction == 0 && volume > 0) volume--;
if(envelope_direction == 1 && volume < 15) volume++; if(envelope_direction == 1 && volume < 15) volume++;
} }

View File

@@ -1,20 +1,20 @@
struct Square2 { struct Square2 {
bool enable; bool enable;
unsigned duty; uint2 duty;
unsigned length; unsigned length;
unsigned envelope_volume; uint4 envelope_volume;
unsigned envelope_direction; bool envelope_direction;
unsigned envelope_frequency; uint3 envelope_frequency;
unsigned frequency; uint11 frequency;
unsigned counter; bool counter;
int16 output; int16 output;
bool duty_output; bool duty_output;
unsigned phase; uint3 phase;
unsigned period; unsigned period;
unsigned envelope_period; uint3 envelope_period;
unsigned volume; uint4 volume;
bool dac_enable(); bool dac_enable();

View File

@@ -3,15 +3,14 @@
void APU::Wave::run() { void APU::Wave::run() {
if(period && --period == 0) { if(period && --period == 0) {
period = 2 * (2048 - frequency); period = 2 * (2048 - frequency);
pattern_offset = (pattern_offset + 1) & 31; pattern_sample = pattern[++pattern_offset];
pattern_sample = pattern[pattern_offset];
} }
uint4 sample = pattern_sample; uint4 sample = pattern_sample;
if(enable == false) sample = 0; if(enable == false) sample = 0;
output = (sample * 4369) - 32768; output = (sample * 4369) - 32768;
output >>= volume; output >>= volume_shift;
} }
void APU::Wave::clock_length() { void APU::Wave::clock_length() {
@@ -32,10 +31,10 @@ void APU::Wave::write(unsigned r, uint8 data) {
if(r == 2) { //$ff1c NR32 if(r == 2) { //$ff1c NR32
switch((data >> 5) & 3) { switch((data >> 5) & 3) {
case 0: volume = 16; break; // 0% case 0: volume_shift = 16; break; // 0%
case 1: volume = 0; break; //100% case 1: volume_shift = 0; break; //100%
case 2: volume = 1; break; // 50% case 2: volume_shift = 1; break; // 50%
case 3: volume = 2; break; // 25% case 3: volume_shift = 2; break; // 25%
} }
} }
@@ -68,7 +67,7 @@ void APU::Wave::power() {
enable = 0; enable = 0;
dac_enable = 0; dac_enable = 0;
volume = 0; volume_shift = 0;
frequency = 0; frequency = 0;
counter = 0; counter = 0;
@@ -86,7 +85,7 @@ void APU::Wave::serialize(serializer &s) {
s.integer(enable); s.integer(enable);
s.integer(dac_enable); s.integer(dac_enable);
s.integer(volume); s.integer(volume_shift);
s.integer(frequency); s.integer(frequency);
s.integer(counter); s.integer(counter);
s.array(pattern); s.array(pattern);

View File

@@ -2,16 +2,16 @@ struct Wave {
bool enable; bool enable;
bool dac_enable; bool dac_enable;
unsigned volume; unsigned volume_shift;
unsigned frequency; uint11 frequency;
bool counter; bool counter;
uint8 pattern[32]; uint8 pattern[32];
int16 output; int16 output;
unsigned length; unsigned length;
unsigned period; unsigned period;
unsigned pattern_offset; uint5 pattern_offset;
unsigned pattern_sample; uint4 pattern_sample;
void run(); void run();
void clock_length(); void clock_length();

View File

@@ -5,7 +5,7 @@
namespace GameBoy { namespace GameBoy {
namespace Info { namespace Info {
static const char Name[] = "bgameboy"; static const char Name[] = "bgameboy";
static const char Version[] = "000.22"; static const char Version[] = "000.23";
static unsigned SerializerVersion = 2; static unsigned SerializerVersion = 2;
} }
} }

View File

@@ -7,6 +7,8 @@ namespace GameBoy {
#include "serialization.cpp" #include "serialization.cpp"
LCD lcd; LCD lcd;
static unsigned linectr;
void LCD::Main() { void LCD::Main() {
lcd.main(); lcd.main();
} }
@@ -60,6 +62,7 @@ void LCD::frame() {
cpu.mmio_joyp_poll(); cpu.mmio_joyp_poll();
status.ly = 0; status.ly = 0;
status.wyc = 0;
scheduler.exit(Scheduler::ExitReason::FrameEvent); scheduler.exit(Scheduler::ExitReason::FrameEvent);
} }
@@ -112,8 +115,9 @@ void LCD::render_bg() {
} }
void LCD::render_window() { void LCD::render_window() {
if(status.ly - status.wy >= 144U) return; if(status.ly - status.wy >= 144u) return;
unsigned iy = status.ly - status.wy; if(status.wx >= 167u) return;
unsigned iy = status.wyc++;
unsigned ix = (7 - status.wx) & 255, tx = ix & 7; unsigned ix = (7 - status.wx) & 255, tx = ix & 7;
unsigned data = read_tile(status.window_tilemap_select, ix, iy); unsigned data = read_tile(status.window_tilemap_select, ix, iy);
@@ -215,6 +219,7 @@ void LCD::power() {
for(unsigned n = 0; n < 160 * 144; n++) screen[n] = 0x00; for(unsigned n = 0; n < 160 * 144; n++) screen[n] = 0x00;
status.lx = 0; status.lx = 0;
status.wyc = 0;
status.display_enable = 0; status.display_enable = 0;
status.window_tilemap_select = 0; status.window_tilemap_select = 0;

View File

@@ -3,6 +3,7 @@ struct LCD : Processor, MMIO {
struct Status { struct Status {
unsigned lx; unsigned lx;
unsigned wyc;
//$ff40 LCDC //$ff40 LCDC
bool display_enable; bool display_enable;

View File

@@ -2,6 +2,7 @@
void LCD::serialize(serializer &s) { void LCD::serialize(serializer &s) {
s.integer(status.lx); s.integer(status.lx);
s.integer(status.wyc);
s.integer(status.display_enable); s.integer(status.display_enable);
s.integer(status.window_tilemap_select); s.integer(status.window_tilemap_select);

View File

@@ -1,7 +1,7 @@
namespace SNES { namespace SNES {
namespace Info { namespace Info {
static const char Name[] = "bsnes"; static const char Name[] = "bsnes";
static const char Version[] = "082.02"; static const char Version[] = "082.03";
static const unsigned SerializerVersion = 21; static const unsigned SerializerVersion = 21;
} }
} }