diff --git a/emulator/emulator.hpp b/emulator/emulator.hpp index b81b8f3f..4eb21859 100644 --- a/emulator/emulator.hpp +++ b/emulator/emulator.hpp @@ -3,7 +3,7 @@ namespace Emulator { static const char Name[] = "higan"; - static const char Version[] = "093.08"; + static const char Version[] = "093.09"; static const char Author[] = "byuu"; static const char License[] = "GPLv3"; static const char Website[] = "http://byuu.org/"; diff --git a/gb/cpu/cpu.cpp b/gb/cpu/cpu.cpp index a7f5cbf4..782815a5 100644 --- a/gb/cpu/cpu.cpp +++ b/gb/cpu/cpu.cpp @@ -200,6 +200,10 @@ void CPU::power() { status.interrupt_enable_timer = 0; status.interrupt_enable_stat = 0; status.interrupt_enable_vblank = 0; + + oamdma.active = false; + oamdma.bank = 0; + oamdma.offset = 0; } } diff --git a/gb/cpu/cpu.hpp b/gb/cpu/cpu.hpp index c9980337..5d492361 100644 --- a/gb/cpu/cpu.hpp +++ b/gb/cpu/cpu.hpp @@ -79,6 +79,12 @@ struct CPU : Processor::LR35902, Thread, MMIO { bool interrupt_enable_vblank; } status; + struct OAMDMA { + bool active; + uint8 bank; + uint8 offset; + } oamdma; + uint8 wram[32768]; //GB=8192, GBC=32768 uint8 hram[128]; diff --git a/gb/cpu/memory.cpp b/gb/cpu/memory.cpp index aec25eff..b19fd368 100644 --- a/gb/cpu/memory.cpp +++ b/gb/cpu/memory.cpp @@ -7,15 +7,16 @@ void CPU::op_io() { uint8 CPU::op_read(uint16 addr) { cycle_edge(); - uint8 r = bus.read(addr); add_clocks(4); - return r; + if(oamdma.active) return hram[addr & 0x7f]; + return bus.read(addr); } void CPU::op_write(uint16 addr, uint8 data) { cycle_edge(); - bus.write(addr, data); add_clocks(4); + if(oamdma.active) hram[addr & 0x7f] = data; + else bus.write(addr, data); } void CPU::cycle_edge() { diff --git a/gb/cpu/mmio.cpp b/gb/cpu/mmio.cpp index 1170420a..7c54d491 100644 --- a/gb/cpu/mmio.cpp +++ b/gb/cpu/mmio.cpp @@ -186,10 +186,9 @@ void CPU::mmio_write(uint16 addr, uint8 data) { } if(addr == 0xff46) { //DMA - for(unsigned n = 0x00; n <= 0x9f; n++) { - bus.write(0xfe00 + n, bus.read((data << 8) + n)); - add_clocks(4); - } + oamdma.active = true; + oamdma.bank = data; + oamdma.offset = 0; return; } diff --git a/gb/cpu/serialization.cpp b/gb/cpu/serialization.cpp index 6a912e13..465b41cf 100644 --- a/gb/cpu/serialization.cpp +++ b/gb/cpu/serialization.cpp @@ -55,6 +55,10 @@ void CPU::serialize(serializer& s) { s.integer(status.interrupt_enable_timer); s.integer(status.interrupt_enable_stat); s.integer(status.interrupt_enable_vblank); + + s.integer(oamdma.active); + s.integer(oamdma.bank); + s.integer(oamdma.offset); } #endif diff --git a/gb/cpu/timing.cpp b/gb/cpu/timing.cpp index dfc0821c..0f31a62c 100644 --- a/gb/cpu/timing.cpp +++ b/gb/cpu/timing.cpp @@ -5,6 +5,16 @@ #ifdef CPU_CPP void CPU::add_clocks(unsigned clocks) { + if(oamdma.active) { + for(unsigned n = 0; n < clocks; n++) { + bus.write(0xfe00 + oamdma.offset, bus.read((oamdma.bank << 8) + oamdma.offset)); + if(++oamdma.offset == 160) { + oamdma.active = false; + break; + } + } + } + system.clocks_executed += clocks; if(system.sgb()) scheduler.exit(Scheduler::ExitReason::StepEvent); diff --git a/gb/ppu/ppu.cpp b/gb/ppu/ppu.cpp index 2b2e44cc..1c5565e0 100644 --- a/gb/ppu/ppu.cpp +++ b/gb/ppu/ppu.cpp @@ -66,6 +66,7 @@ void PPU::scanline() { if(++status.ly == 154) frame(); if(status.ly < 144) { + interface->lcdScanline(); //Super Game Boy rendering notification system.cgb() ? cgb_scanline() : dmg_scanline(); } @@ -80,8 +81,6 @@ void PPU::scanline() { } void PPU::frame() { - cpu.mmio_joyp_poll(); - status.ly = 0; scheduler.exit(Scheduler::ExitReason::FrameEvent); } diff --git a/phoenix/core/core.cpp b/phoenix/core/core.cpp index 33f9ce41..76da6b1a 100644 --- a/phoenix/core/core.cpp +++ b/phoenix/core/core.cpp @@ -1491,6 +1491,8 @@ void ListView::remove(unsigned selection) { void ListView::reset() { state.checked.reset(); state.image.reset(); + state.selected = false; + state.selection = 0; state.text.reset(); return p.reset(); } diff --git a/target-ethos/configuration/configuration.cpp b/target-ethos/configuration/configuration.cpp index d40e5532..214a12b1 100644 --- a/target-ethos/configuration/configuration.cpp +++ b/target-ethos/configuration/configuration.cpp @@ -2,7 +2,7 @@ ConfigurationSettings* config = nullptr; ConfigurationSettings::ConfigurationSettings() { - video.append(video.driver = ruby::video.safestDriver(), "Driver"); + video.append(video.driver = ruby::video.optimalDriver(), "Driver"); video.append(video.synchronize = false, "Synchronize"); video.append(video.shader = "Blur", "Shader"); video.append(video.scaleMode = 0, "ScaleMode"); @@ -18,7 +18,7 @@ ConfigurationSettings::ConfigurationSettings() { video.append(video.startFullScreen = false, "StartFullScreen"); append(video, "Video"); - audio.append(audio.driver = ruby::audio.safestDriver(), "Driver"); + audio.append(audio.driver = ruby::audio.optimalDriver(), "Driver"); audio.append(audio.synchronize = true, "Synchronize"); audio.append(audio.frequency = 48000, "Frequency"); audio.append(audio.latency = 60, "Latency"); @@ -27,7 +27,7 @@ ConfigurationSettings::ConfigurationSettings() { audio.append(audio.mute = false, "Mute"); append(audio, "Audio"); - input.append(input.driver = ruby::input.safestDriver(), "Driver"); + input.append(input.driver = ruby::input.optimalDriver(), "Driver"); input.focus.append(input.focus.pause = false, "Pause"); input.focus.append(input.focus.allow = false, "AllowInput"); input.append(input.focus, "Focus"); diff --git a/target-ethos/general/library.cpp b/target-ethos/general/library.cpp index c4950879..3ce67235 100644 --- a/target-ethos/general/library.cpp +++ b/target-ethos/general/library.cpp @@ -203,7 +203,7 @@ string LibraryManager::load(const string& type) { show(); setModal(); slotLoad = false; - browser->mediaMode.setSelection(0); + browser->mediaMode.setSelection(config->library.mediaMode = 0); return loadPathname; } mode++; @@ -287,7 +287,10 @@ void LibraryManager::synchronize() { if(requestedLoadType.empty()) { loadButton.setEnabled(media.bootable); } else { - loadButton.setEnabled(requestedLoadType == media.type); + bool enabled = (requestedLoadType == media.type); + //allow Super Game Boy to load Game Boy Color games + if(requestedLoadType == "gb" && loaded.size() == 1 && media.type == "gbc") enabled = true; + loadButton.setEnabled(enabled); } } else { loadButton.setEnabled(false);