Update to v083r07 release.

byuu says:

Game Boy: audio should sound a lot better, eg Zelda: DX first opening
scene
Game Boy Color: now uses cothread Processor::frequency to dynamically
clock GB-CPU to 8MHz. Proper OAM DMA and timer speed. Fixes SMT: DC - WB
audio.
Added the break; statements to phoenix/windows/platform message loop
Added audio latency/frequency to config file only
This commit is contained in:
Tim Allen 2011-10-28 20:51:43 +11:00
parent aaffd000a4
commit f3feaa3e86
16 changed files with 60 additions and 56 deletions

View File

@ -47,7 +47,9 @@ void APU::main() {
master.run();
interface->audioSample(master.center, master.left, master.right);
if(++clock >= 0) co_switch(scheduler.active_thread = cpu.thread);
clock += 1 * cpu.frequency;
if(clock >= 0) co_switch(scheduler.active_thread = cpu.thread);
}
}

View File

@ -1,11 +1,6 @@
#ifdef APU_CPP
void APU::Master::run() {
static int16_t volume[] = {
-16384, -14336, -12288, -10240, -8192, -6144, -4096, -2048,
+2048, +4096, +6144, +8192, +10240, +12288, +14336, +16384,
};
if(enable == false) {
center = 0;
left = 0;
@ -13,22 +8,19 @@ void APU::Master::run() {
return;
}
signed sample = 0, channels;
signed sample = 0;
sample += apu.square1.output;
sample += apu.square2.output;
sample += apu.wave.output;
sample += apu.noise.output;
sample >>= 2;
center = volume[sample];
center = (sample * 512) - 16384;
sample = 0;
channels = 0;
if(channel1_left_enable) { sample += apu.square1.output; channels++; }
if(channel2_left_enable) { sample += apu.square2.output; channels++; }
if(channel3_left_enable) { sample += apu.wave.output; channels++; }
if(channel4_left_enable) { sample += apu.noise.output; channels++; }
if(channels) sample /= channels;
left = volume[sample];
if(channel1_left_enable) sample += apu.square1.output;
if(channel2_left_enable) sample += apu.square2.output;
if(channel3_left_enable) sample += apu.wave.output;
if(channel4_left_enable) sample += apu.noise.output;
left = (sample * 512) - 16384;
switch(left_volume) {
case 0: left >>= 3; break; // 12.5%
@ -42,13 +34,11 @@ void APU::Master::run() {
}
sample = 0;
channels = 0;
if(channel1_right_enable) { sample += apu.square1.output; channels++; }
if(channel2_right_enable) { sample += apu.square2.output; channels++; }
if(channel3_right_enable) { sample += apu.wave.output; channels++; }
if(channel4_right_enable) { sample += apu.noise.output; channels++; }
if(channels) sample /= channels;
right = volume[sample];
if(channel1_right_enable) sample += apu.square1.output;
if(channel2_right_enable) sample += apu.square2.output;
if(channel3_right_enable) sample += apu.wave.output;
if(channel4_right_enable) sample += apu.noise.output;
right = (sample * 512) - 16384;
switch(right_volume) {
case 0: right >>= 3; break; // 12.5%

View File

@ -574,6 +574,8 @@ void CPU::op_stop() {
if(status.speed_switch) {
status.speed_switch = 0;
status.speed_double ^= 1;
frequency = 4 * 1024 * 1024;
if(status.speed_double) frequency *= 2;
return;
}
status.stop = true;

View File

@ -219,7 +219,7 @@ void CPU::mmio_write(uint16 addr, uint8 data) {
if(status.dma_mode == 0) do {
bus.write(status.dma_target++, bus.read(status.dma_source++));
add_clocks(4);
add_clocks(4 << status.speed_double);
} while(--status.dma_length);
return;
}

View File

@ -2,20 +2,20 @@
void CPU::op_io() {
cycle_edge();
add_clocks(4 >> status.speed_double);
add_clocks(4);
}
uint8 CPU::op_read(uint16 addr) {
cycle_edge();
uint8 r = bus.read(addr);
add_clocks(4 >> status.speed_double);
add_clocks(4);
return r;
}
void CPU::op_write(uint16 addr, uint8 data) {
cycle_edge();
bus.write(addr, data);
add_clocks(4 >> status.speed_double);
add_clocks(4);
}
void CPU::cycle_edge() {

View File

@ -8,7 +8,7 @@
void CPU::add_clocks(unsigned clocks) {
system.clocks_executed += clocks;
scheduler.exit(Scheduler::ExitReason::StepEvent);
if(system.sgb()) scheduler.exit(Scheduler::ExitReason::StepEvent);
status.clock += clocks;
if(status.clock >= 4 * 1024 * 1024) {
@ -23,10 +23,10 @@ void CPU::add_clocks(unsigned clocks) {
if((status.clock & 511) == 0) timer_8192hz();
if((status.clock & 1023) == 0) timer_4096hz();
lcd.clock -= clocks;
lcd.clock -= clocks * lcd.frequency;
if(lcd.clock <= 0) co_switch(scheduler.active_thread = lcd.thread);
apu.clock -= clocks;
apu.clock -= clocks * apu.frequency;
if(apu.clock <= 0) co_switch(scheduler.active_thread = apu.thread);
}

View File

@ -2,17 +2,17 @@
void LCD::cgb_render() {
for(unsigned n = 0; n < 160; n++) {
line[n] = 0x0000;
line[n] = 0x7fff;
origin[n] = Origin::None;
}
if(status.display_enable == true) {
if(status.display_enable) {
cgb_render_bg();
if(status.window_display_enable == true) cgb_render_window();
if(status.obj_enable == true) cgb_render_ob();
if(status.window_display_enable) cgb_render_window();
if(status.ob_enable) cgb_render_ob();
}
uint16_t *output = screen + status.ly * 160;
uint16 *output = screen + status.ly * 160;
for(unsigned n = 0; n < 160; n++) output[n] = line[n];
interface->lcdScanline();
}
@ -107,7 +107,7 @@ void LCD::cgb_render_window() {
//0x08: VRAM bank#
//0x07: palette#
void LCD::cgb_render_ob() {
const unsigned Height = (status.obj_size == 0 ? 8 : 16);
const unsigned Height = (status.ob_size == 0 ? 8 : 16);
unsigned sprite[10], sprites = 0;
//find first ten sprites on this scanline

View File

@ -6,13 +6,13 @@ void LCD::dmg_render() {
origin[n] = Origin::None;
}
if(status.display_enable == true) {
if(status.bg_enable == true) dmg_render_bg();
if(status.window_display_enable == true) dmg_render_window();
if(status.obj_enable == true) dmg_render_ob();
if(status.display_enable) {
if(status.bg_enable) dmg_render_bg();
if(status.window_display_enable) dmg_render_window();
if(status.ob_enable) dmg_render_ob();
}
uint16_t *output = screen + status.ly * 160;
uint16 *output = screen + status.ly * 160;
for(unsigned n = 0; n < 160; n++) output[n] = line[n];
interface->lcdScanline();
}
@ -76,7 +76,7 @@ void LCD::dmg_render_window() {
//0x20: horizontal flip
//0x10: palette#
void LCD::dmg_render_ob() {
const unsigned Height = (status.obj_size == 0 ? 8 : 16);
const unsigned Height = (status.ob_size == 0 ? 8 : 16);
unsigned sprite[10], sprites = 0;
//find first ten sprites on this scanline

View File

@ -41,7 +41,7 @@ void LCD::main() {
}
void LCD::add_clocks(unsigned clocks) {
clock += clocks;
clock += clocks * cpu.frequency;
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) {
co_switch(scheduler.active_thread = cpu.thread);
}
@ -127,8 +127,8 @@ void LCD::power() {
status.window_display_enable = 0;
status.bg_tiledata_select = 0;
status.bg_tilemap_select = 0;
status.obj_size = 0;
status.obj_enable = 0;
status.ob_size = 0;
status.ob_enable = 0;
status.bg_enable = 0;
status.interrupt_lyc = 0;

View File

@ -11,8 +11,8 @@ struct LCD : Processor, MMIO {
bool window_display_enable;
bool bg_tiledata_select;
bool bg_tilemap_select;
bool obj_size;
bool obj_enable;
bool ob_size;
bool ob_enable;
bool bg_enable;
//$ff41 STAT

View File

@ -14,8 +14,8 @@ uint8 LCD::mmio_read(uint16 addr) {
| (status.window_display_enable << 5)
| (status.bg_tiledata_select << 4)
| (status.bg_tilemap_select << 3)
| (status.obj_size << 2)
| (status.obj_enable << 1)
| (status.ob_size << 2)
| (status.ob_enable << 1)
| (status.bg_enable << 0);
}
@ -104,8 +104,8 @@ void LCD::mmio_write(uint16 addr, uint8 data) {
status.window_display_enable = data & 0x20;
status.bg_tiledata_select = data & 0x10;
status.bg_tilemap_select = data & 0x08;
status.obj_size = data & 0x04;
status.obj_enable = data & 0x02;
status.ob_size = data & 0x04;
status.ob_enable = data & 0x02;
status.bg_enable = data & 0x01;
return;
}

View File

@ -23,8 +23,8 @@ void LCD::serialize(serializer &s) {
s.integer(status.window_display_enable);
s.integer(status.bg_tiledata_select);
s.integer(status.bg_tilemap_select);
s.integer(status.obj_size);
s.integer(status.obj_enable);
s.integer(status.ob_size);
s.integer(status.ob_enable);
s.integer(status.bg_enable);
s.integer(status.interrupt_lyc);

View File

@ -299,6 +299,7 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
//mmi->ptMinTrackSize.x = 256 + window.p.frameMargin().width;
//mmi->ptMinTrackSize.y = 256 + window.p.frameMargin().height;
//return TRUE;
break;
}
case WM_ERASEBKGND: {
@ -320,6 +321,7 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
SetBkColor((HDC)wparam, window.p.brushColor);
return (INT_PTR)window.p.brush;
}
break;
}
case WM_COMMAND: {
@ -378,6 +380,7 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
}
}
}
break;
}
case WM_NOTIFY: {
@ -412,6 +415,7 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
if(listView.onActivate) listView.onActivate();
}
}
break;
}
case WM_HSCROLL:
@ -481,6 +485,8 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
if(verticalSlider.onChange) verticalSlider.onChange();
}
}
break;
}
}

View File

@ -24,7 +24,9 @@ Config::Config() {
attach(audio.synchronize = true, "Audio::Synchronize");
attach(audio.mute = false, "Audio::Mute");
attach(audio.volume = 100, "Audio::Volume");
attach(audio.latency = 60, "Audio::Latency");
attach(audio.frequency = 48000, "Audio::Frequency::Native");
attach(audio.frequencyNES = 1789772, "Audio::Frequency::NES");
attach(audio.frequencySNES = 32000, "Audio::Frequency::SNES");
attach(audio.frequencyGameBoy = 4194304, "Audio::Frequency::GameBoy");

View File

@ -24,7 +24,9 @@ struct Config : public configuration {
bool synchronize;
bool mute;
unsigned volume;
unsigned latency;
unsigned frequency;
unsigned frequencyNES;
unsigned frequencySNES;
unsigned frequencyGameBoy;

View File

@ -27,7 +27,7 @@ void Application::run() {
}
Application::Application(int argc, char **argv) {
title = "bsnes v083.06";
title = "bsnes v083.07";
application = this;
quit = false;
@ -80,8 +80,8 @@ Application::Application(int argc, char **argv) {
audio.driver(config->audio.driver);
audio.set(Audio::Handle, mainWindow->viewport.handle());
audio.set(Audio::Synchronize, config->audio.synchronize);
audio.set(Audio::Latency, 60u);
audio.set(Audio::Frequency, 48000u);
audio.set(Audio::Latency, config->audio.latency);
audio.set(Audio::Frequency, config->audio.frequency);
audio.init();
dspaudio.setPrecision(16);