mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
aaffd000a4
commit
f3feaa3e86
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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%
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -24,7 +24,9 @@ struct Config : public configuration {
|
|||
bool synchronize;
|
||||
bool mute;
|
||||
unsigned volume;
|
||||
unsigned latency;
|
||||
|
||||
unsigned frequency;
|
||||
unsigned frequencyNES;
|
||||
unsigned frequencySNES;
|
||||
unsigned frequencyGameBoy;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue