From bdc100e123d91439d065cdd283713f59a9201be1 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Mon, 23 Jan 2017 08:04:26 +1100 Subject: [PATCH] Update to v102r02 release. byuu says: Changelog: - I caved on the `samples[] = {0.0}` thing, but I'm very unhappy about it - if it's really invalid C++, then GCC needs to stop accepting it in strict `-std=c++14` mode - Emulator::Interface::Information::resettable is gone - Emulator::Interface::reset() is gone - FC, SFC, MD cores updated to remove soft reset behavior - split GameBoy::Interface into GameBoyInterface, GameBoyColorInterface - split WonderSwan::Interface into WonderSwanInterface, WonderSwanColorInterface - PCE: fixed off-by-one scanline error [hex_usr] - PCE: temporary hack to prevent crashing when VDS is set to < 2 - hiro: Cocoa: removed (u)int(#) constants; converted (u)int(#) types to (u)int_(#)t types - icarus: replaced usage of unique with strip instead (so we don't mess up frameworks on macOS) - libco: added macOS-specific section marker [Ryphecha] So ... the major news this time is the removal of the soft reset behavior. This is a major!! change that results in a 100KiB diff file, and it's very prone to accidental mistakes!! If anyone is up for testing, or even better -- looking over the code changes between v102r01 and v102r02 and looking for any issues, please do so. Ideally we'll want to test every NES mapper type and every SNES coprocessor type by loading said games and power cycling to make sure the games are all cleanly resetting. It's too big of a change for me to cover there not being any issues on my own, but this is truly critical code, so yeah ... please help if you can. We technically lose a bit of hardware documentation here. The soft reset events do all kinds of interesting things in all kinds of different chips -- or at least they do on the SNES. This is obviously not ideal. But in the process of removing these portions of code, I found a few mistakes I had made previously. It simplifies resetting the system state a lot when not trying to have all the power() functions call the reset() functions to share partial functionality. In the future, the goal will be to come up with a way to add back in the soft reset behavior via keyboard binding as with the Master System core. What's going to have to happen is that the key binding will have to send a "reset pulse" to every emulated chip, and those chips are going to have to act independently to power() instead of reusing functionality. We'll get there eventually, but there's many things of vastly greater importance to work on right now, so it'll be a while. The information isn't lost ... we'll just have to pull it out of v102 when we are ready. Note that I left the SNES reset vector simulation code in, even though it's not possible to trigger, for the time being. Also ... the Super Game Boy core is still disconnected. To be honest, it totally slipped my mind when I released v102 that it wasn't connected again yet. This one's going to be pretty tricky to be honest. I'm thinking about making a third GameBoy::Interface class just for SGB, and coming up with some way of bypassing platform-> calls when in this mode. --- higan/audio/audio.cpp | 8 +- higan/emulator/emulator.hpp | 2 +- higan/emulator/interface.hpp | 2 - higan/fc/apu/apu.cpp | 14 +- higan/fc/apu/apu.hpp | 7 - higan/fc/apu/dmc.cpp | 3 - higan/fc/apu/envelope.cpp | 3 - higan/fc/apu/noise.cpp | 3 - higan/fc/apu/pulse.cpp | 5 - higan/fc/apu/sweep.cpp | 3 - higan/fc/apu/triangle.cpp | 4 - higan/fc/cartridge/board/board.cpp | 3 - higan/fc/cartridge/board/board.hpp | 1 - higan/fc/cartridge/board/konami-vrc1.cpp | 4 - higan/fc/cartridge/board/konami-vrc2.cpp | 4 - higan/fc/cartridge/board/konami-vrc3.cpp | 4 - higan/fc/cartridge/board/konami-vrc4.cpp | 4 - higan/fc/cartridge/board/konami-vrc6.cpp | 1 - higan/fc/cartridge/board/konami-vrc7.cpp | 4 - higan/fc/cartridge/board/nes-axrom.cpp | 3 - higan/fc/cartridge/board/nes-bnrom.cpp | 3 - higan/fc/cartridge/board/nes-cnrom.cpp | 3 - higan/fc/cartridge/board/nes-exrom.cpp | 4 - higan/fc/cartridge/board/nes-fxrom.cpp | 3 - higan/fc/cartridge/board/nes-gxrom.cpp | 3 - higan/fc/cartridge/board/nes-hkrom.cpp | 4 - higan/fc/cartridge/board/nes-nrom.cpp | 3 + higan/fc/cartridge/board/nes-pxrom.cpp | 3 - higan/fc/cartridge/board/nes-sxrom.cpp | 4 - higan/fc/cartridge/board/nes-txrom.cpp | 4 - higan/fc/cartridge/board/nes-uxrom.cpp | 3 - higan/fc/cartridge/board/sunsoft-5b.cpp | 12 +- higan/fc/cartridge/cartridge.cpp | 6 +- higan/fc/cartridge/cartridge.hpp | 1 - higan/fc/cartridge/chip/mmc1.cpp | 3 - higan/fc/cartridge/chip/mmc3.cpp | 3 - higan/fc/cartridge/chip/mmc5.cpp | 3 - higan/fc/cartridge/chip/mmc6.cpp | 3 - higan/fc/cartridge/chip/vrc1.cpp | 3 - higan/fc/cartridge/chip/vrc2.cpp | 3 - higan/fc/cartridge/chip/vrc3.cpp | 3 - higan/fc/cartridge/chip/vrc4.cpp | 3 - higan/fc/cartridge/chip/vrc6.cpp | 3 - higan/fc/cartridge/chip/vrc7.cpp | 3 - higan/fc/cpu/cpu.cpp | 6 +- higan/fc/cpu/cpu.hpp | 1 - higan/fc/interface/interface.cpp | 5 - higan/fc/interface/interface.hpp | 1 - higan/fc/ppu/ppu.cpp | 3 - higan/fc/ppu/ppu.hpp | 1 - higan/fc/system/system.cpp | 16 +- higan/fc/system/system.hpp | 1 - higan/gb/interface/game-boy-color.cpp | 149 +++++++++++++ higan/gb/interface/game-boy.cpp | 164 ++++++++++++++ higan/gb/interface/interface.cpp | 210 +----------------- higan/gb/interface/interface.hpp | 44 +++- higan/gba/interface/interface.cpp | 5 - higan/gba/interface/interface.hpp | 1 - higan/md/cartridge/cartridge.cpp | 3 - higan/md/cartridge/cartridge.hpp | 1 - higan/md/cpu/cpu.cpp | 4 - higan/md/cpu/cpu.hpp | 1 - higan/md/interface/interface.cpp | 5 - higan/md/interface/interface.hpp | 1 - higan/md/psg/psg.cpp | 3 - higan/md/psg/psg.hpp | 1 - higan/md/system/system.cpp | 20 +- higan/md/system/system.hpp | 1 - higan/md/vdp/background.cpp | 3 - higan/md/vdp/sprite.cpp | 3 - higan/md/vdp/vdp.cpp | 17 +- higan/md/vdp/vdp.hpp | 3 - higan/md/ym2612/ym2612.cpp | 3 - higan/md/ym2612/ym2612.hpp | 1 - higan/ms/interface/game-gear.cpp | 1 - higan/ms/interface/master-system.cpp | 1 - higan/pce/interface/interface.cpp | 1 - higan/pce/vdc/vdc.cpp | 6 +- higan/processor/gsu/gsu.cpp | 3 - higan/processor/gsu/gsu.hpp | 1 - higan/processor/m68k/instruction.cpp | 11 - higan/processor/m68k/m68k.cpp | 5 - higan/processor/m68k/m68k.hpp | 2 - higan/processor/r6502/r6502.cpp | 7 +- higan/processor/r6502/r6502.hpp | 1 - higan/sfc/coprocessor/armdsp/armdsp.cpp | 9 +- higan/sfc/coprocessor/armdsp/armdsp.hpp | 3 +- higan/sfc/coprocessor/epsonrtc/epsonrtc.cpp | 3 - higan/sfc/coprocessor/epsonrtc/epsonrtc.hpp | 1 - higan/sfc/coprocessor/event/event.cpp | 3 - higan/sfc/coprocessor/event/event.hpp | 1 - .../sfc/coprocessor/hitachidsp/hitachidsp.cpp | 8 +- .../sfc/coprocessor/hitachidsp/hitachidsp.hpp | 1 - higan/sfc/coprocessor/icd2/icd2.cpp | 9 +- higan/sfc/coprocessor/icd2/icd2.hpp | 2 +- higan/sfc/coprocessor/mcc/mcc.cpp | 3 - higan/sfc/coprocessor/mcc/mcc.hpp | 1 - higan/sfc/coprocessor/msu1/msu1.cpp | 3 - higan/sfc/coprocessor/msu1/msu1.hpp | 1 - higan/sfc/coprocessor/necdsp/necdsp.cpp | 5 +- higan/sfc/coprocessor/necdsp/necdsp.hpp | 1 - higan/sfc/coprocessor/nss/nss.cpp | 3 - higan/sfc/coprocessor/nss/nss.hpp | 1 - higan/sfc/coprocessor/obc1/obc1.cpp | 3 - higan/sfc/coprocessor/obc1/obc1.hpp | 1 - higan/sfc/coprocessor/sa1/sa1.cpp | 14 +- higan/sfc/coprocessor/sa1/sa1.hpp | 1 - higan/sfc/coprocessor/sdd1/sdd1.cpp | 3 - higan/sfc/coprocessor/sdd1/sdd1.hpp | 1 - higan/sfc/coprocessor/sharprtc/sharprtc.cpp | 3 - higan/sfc/coprocessor/sharprtc/sharprtc.hpp | 1 - higan/sfc/coprocessor/spc7110/spc7110.cpp | 3 - higan/sfc/coprocessor/spc7110/spc7110.hpp | 1 - higan/sfc/coprocessor/superfx/superfx.cpp | 4 - higan/sfc/coprocessor/superfx/superfx.hpp | 1 - higan/sfc/cpu/cpu.cpp | 85 +++---- higan/sfc/cpu/cpu.hpp | 1 - higan/sfc/dsp/dsp.cpp | 18 +- higan/sfc/dsp/dsp.hpp | 1 - higan/sfc/interface/interface.cpp | 5 - higan/sfc/interface/interface.hpp | 1 - higan/sfc/ppu/background/background.cpp | 2 +- higan/sfc/ppu/background/background.hpp | 2 +- higan/sfc/ppu/object/object.cpp | 2 +- higan/sfc/ppu/object/object.hpp | 2 +- higan/sfc/ppu/ppu.cpp | 20 +- higan/sfc/ppu/ppu.hpp | 1 - higan/sfc/ppu/screen/screen.cpp | 2 +- higan/sfc/ppu/screen/screen.hpp | 2 +- higan/sfc/ppu/window/window.cpp | 2 +- higan/sfc/ppu/window/window.hpp | 2 +- higan/sfc/slot/bsmemory/bsmemory.cpp | 3 - higan/sfc/slot/bsmemory/bsmemory.hpp | 1 - higan/sfc/smp/smp.cpp | 11 +- higan/sfc/smp/smp.hpp | 1 - higan/sfc/system/system.cpp | 45 +--- higan/sfc/system/system.hpp | 1 - higan/target-tomoko/program/program.cpp | 6 +- higan/ws/interface/interface.cpp | 162 +------------- higan/ws/interface/interface.hpp | 39 +++- higan/ws/interface/wonderswan-color.cpp | 156 +++++++++++++ higan/ws/interface/wonderswan.cpp | 156 +++++++++++++ hiro/cocoa/header.hpp | 16 -- hiro/cocoa/widget/canvas.cpp | 4 +- icarus/GNUmakefile | 2 +- libco/libco.h | 2 +- libco/settings.h | 18 +- 147 files changed, 855 insertions(+), 894 deletions(-) create mode 100644 higan/gb/interface/game-boy-color.cpp create mode 100644 higan/gb/interface/game-boy.cpp create mode 100644 higan/ws/interface/wonderswan-color.cpp create mode 100644 higan/ws/interface/wonderswan.cpp diff --git a/higan/audio/audio.cpp b/higan/audio/audio.cpp index 0e17c773..1d532cc1 100644 --- a/higan/audio/audio.cpp +++ b/higan/audio/audio.cpp @@ -56,13 +56,15 @@ auto Audio::process() -> void { if(!stream->pending()) return; } - double samples[channels] = {0.0}; + double samples[channels]; + for(auto& sample : samples) sample = 0.0; + for(auto& stream : streams) { double buffer[16]; uint length = stream->read(buffer), offset = 0; - for(auto c : range(channels)) { - samples[c] += buffer[offset]; + for(auto& sample : samples) { + sample += buffer[offset]; if(++offset >= length) offset = 0; } } diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index d859cd3d..5da2eb1c 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "102.01"; + static const string Version = "102.02"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/emulator/interface.hpp b/higan/emulator/interface.hpp index 10297494..7f3b95ea 100644 --- a/higan/emulator/interface.hpp +++ b/higan/emulator/interface.hpp @@ -19,7 +19,6 @@ struct Interface { string manufacturer; string name; bool overscan; - bool resettable; struct Capability { bool states; bool cheats; @@ -75,7 +74,6 @@ struct Interface { //system interface virtual auto connect(uint port, uint device) -> void {} virtual auto power() -> void {} - virtual auto reset() -> void {} virtual auto run() -> void {} //time functions diff --git a/higan/fc/apu/apu.cpp b/higan/fc/apu/apu.cpp index 2f4e4c69..2c7ef4eb 100644 --- a/higan/fc/apu/apu.cpp +++ b/higan/fc/apu/apu.cpp @@ -76,6 +76,9 @@ auto APU::setSample(int16 sample) -> void { } auto APU::power() -> void { + create(APU::Enter, system.colorburst() * 6.0); + stream = Emulator::audio.createStream(1, system.colorburst() / 2.0); + filter.hipassStrong = 0; filter.hipassWeak = 0; filter.lopass = 0; @@ -85,17 +88,6 @@ auto APU::power() -> void { triangle.power(); noise.power(); dmc.power(); -} - -auto APU::reset() -> void { - create(APU::Enter, system.colorburst() * 6.0); - stream = Emulator::audio.createStream(1, system.colorburst() / 2.0); - - pulse[0].reset(); - pulse[1].reset(); - triangle.reset(); - noise.reset(); - dmc.reset(); frame.irqPending = 0; diff --git a/higan/fc/apu/apu.hpp b/higan/fc/apu/apu.hpp index d0cc83f4..9e041476 100644 --- a/higan/fc/apu/apu.hpp +++ b/higan/fc/apu/apu.hpp @@ -10,7 +10,6 @@ struct APU : Thread { auto setSample(int16 sample) -> void; auto power() -> void; - auto reset() -> void; auto readIO(uint16 addr) -> uint8; auto writeIO(uint16 addr, uint8 data) -> void; @@ -36,7 +35,6 @@ struct APU : Thread { auto clock() -> void; auto power() -> void; - auto reset() -> void; auto serialize(serializer&) -> void; @@ -54,7 +52,6 @@ struct APU : Thread { auto clock(uint channel) -> void; auto power() -> void; - auto reset() -> void; auto serialize(serializer&) -> void; @@ -73,7 +70,6 @@ struct APU : Thread { auto clock() -> uint8; auto power() -> void; - auto reset() -> void; auto serialize(serializer&) -> void; @@ -95,7 +91,6 @@ struct APU : Thread { auto clock() -> uint8; auto power() -> void; - auto reset() -> void; auto serialize(serializer&) -> void; @@ -117,7 +112,6 @@ struct APU : Thread { auto clock() -> uint8; auto power() -> void; - auto reset() -> void; auto serialize(serializer&) -> void; @@ -138,7 +132,6 @@ struct APU : Thread { auto clock() -> uint8; auto power() -> void; - auto reset() -> void; auto serialize(serializer&) -> void; diff --git a/higan/fc/apu/dmc.cpp b/higan/fc/apu/dmc.cpp index e829ebd0..b71be098 100644 --- a/higan/fc/apu/dmc.cpp +++ b/higan/fc/apu/dmc.cpp @@ -69,9 +69,6 @@ auto APU::DMC::clock() -> uint8 { } auto APU::DMC::power() -> void { -} - -auto APU::DMC::reset() -> void { lengthCounter = 0; irqPending = 0; diff --git a/higan/fc/apu/envelope.cpp b/higan/fc/apu/envelope.cpp index dcdeb40e..d70cf511 100644 --- a/higan/fc/apu/envelope.cpp +++ b/higan/fc/apu/envelope.cpp @@ -17,9 +17,6 @@ auto APU::Envelope::clock() -> void { } auto APU::Envelope::power() -> void { -} - -auto APU::Envelope::reset() -> void { speed = 0; useSpeedAsVolume = 0; loopMode = 0; diff --git a/higan/fc/apu/noise.cpp b/higan/fc/apu/noise.cpp index dcd9ce96..9e19b1c3 100644 --- a/higan/fc/apu/noise.cpp +++ b/higan/fc/apu/noise.cpp @@ -26,9 +26,6 @@ auto APU::Noise::clock() -> uint8 { } auto APU::Noise::power() -> void { -} - -auto APU::Noise::reset() -> void { lengthCounter = 0; envelope.speed = 0; diff --git a/higan/fc/apu/pulse.cpp b/higan/fc/apu/pulse.cpp index 46501287..dea73908 100644 --- a/higan/fc/apu/pulse.cpp +++ b/higan/fc/apu/pulse.cpp @@ -23,11 +23,6 @@ auto APU::Pulse::clock() -> uint8 { auto APU::Pulse::power() -> void { envelope.power(); sweep.power(); -} - -auto APU::Pulse::reset() -> void { - envelope.reset(); - sweep.reset(); lengthCounter = 0; diff --git a/higan/fc/apu/sweep.cpp b/higan/fc/apu/sweep.cpp index 3da33cea..6a25b688 100644 --- a/higan/fc/apu/sweep.cpp +++ b/higan/fc/apu/sweep.cpp @@ -38,6 +38,3 @@ auto APU::Sweep::power() -> void { reload = 0; pulsePeriod = 0; } - -auto APU::Sweep::reset() -> void { -} diff --git a/higan/fc/apu/triangle.cpp b/higan/fc/apu/triangle.cpp index 1e89b347..82d1a284 100644 --- a/higan/fc/apu/triangle.cpp +++ b/higan/fc/apu/triangle.cpp @@ -28,10 +28,6 @@ auto APU::Triangle::clock() -> uint8 { } auto APU::Triangle::power() -> void { - reset(); -} - -auto APU::Triangle::reset() -> void { lengthCounter = 0; linearLength = 0; diff --git a/higan/fc/cartridge/board/board.cpp b/higan/fc/cartridge/board/board.cpp index fdfa5149..3ca0da46 100644 --- a/higan/fc/cartridge/board/board.cpp +++ b/higan/fc/cartridge/board/board.cpp @@ -131,9 +131,6 @@ auto Board::writeCHR(uint addr, uint8 data) -> void { auto Board::power() -> void { } -auto Board::reset() -> void { -} - auto Board::serialize(serializer& s) -> void { if(prgram.size) s.array(prgram.data, prgram.size); if(chrram.size) s.array(chrram.data, chrram.size); diff --git a/higan/fc/cartridge/board/board.hpp b/higan/fc/cartridge/board/board.hpp index e4440ec3..4f24f4ae 100644 --- a/higan/fc/cartridge/board/board.hpp +++ b/higan/fc/cartridge/board/board.hpp @@ -32,7 +32,6 @@ struct Board { virtual inline auto scanline(uint y) -> void {} virtual auto power() -> void; - virtual auto reset() -> void; virtual auto serialize(serializer&) -> void; diff --git a/higan/fc/cartridge/board/konami-vrc1.cpp b/higan/fc/cartridge/board/konami-vrc1.cpp index 7c2a4164..974184e3 100644 --- a/higan/fc/cartridge/board/konami-vrc1.cpp +++ b/higan/fc/cartridge/board/konami-vrc1.cpp @@ -25,10 +25,6 @@ struct KonamiVRC1 : Board { vrc1.power(); } - auto reset() -> void { - vrc1.reset(); - } - auto serialize(serializer& s) -> void { Board::serialize(s); vrc1.serialize(s); diff --git a/higan/fc/cartridge/board/konami-vrc2.cpp b/higan/fc/cartridge/board/konami-vrc2.cpp index 00952b3d..e5d7f874 100644 --- a/higan/fc/cartridge/board/konami-vrc2.cpp +++ b/higan/fc/cartridge/board/konami-vrc2.cpp @@ -35,10 +35,6 @@ struct KonamiVRC2 : Board { vrc2.power(); } - auto reset() -> void { - vrc2.reset(); - } - auto serialize(serializer& s) -> void { Board::serialize(s); vrc2.serialize(s); diff --git a/higan/fc/cartridge/board/konami-vrc3.cpp b/higan/fc/cartridge/board/konami-vrc3.cpp index f71b4a53..a16f9266 100644 --- a/higan/fc/cartridge/board/konami-vrc3.cpp +++ b/higan/fc/cartridge/board/konami-vrc3.cpp @@ -38,10 +38,6 @@ struct KonamiVRC3 : Board { vrc3.power(); } - auto reset() -> void { - vrc3.reset(); - } - auto serialize(serializer& s) -> void { Board::serialize(s); vrc3.serialize(s); diff --git a/higan/fc/cartridge/board/konami-vrc4.cpp b/higan/fc/cartridge/board/konami-vrc4.cpp index a8b9f3fe..c0a53a39 100644 --- a/higan/fc/cartridge/board/konami-vrc4.cpp +++ b/higan/fc/cartridge/board/konami-vrc4.cpp @@ -39,10 +39,6 @@ struct KonamiVRC4 : Board { vrc4.power(); } - auto reset() -> void { - vrc4.reset(); - } - auto serialize(serializer& s) -> void { Board::serialize(s); vrc4.serialize(s); diff --git a/higan/fc/cartridge/board/konami-vrc6.cpp b/higan/fc/cartridge/board/konami-vrc6.cpp index 00a7d6bf..fb1c670f 100644 --- a/higan/fc/cartridge/board/konami-vrc6.cpp +++ b/higan/fc/cartridge/board/konami-vrc6.cpp @@ -34,7 +34,6 @@ struct KonamiVRC6 : Board { auto main() -> void { vrc6.main(); } auto power() -> void { vrc6.power(); } - auto reset() -> void { vrc6.reset(); } VRC6 vrc6; }; diff --git a/higan/fc/cartridge/board/konami-vrc7.cpp b/higan/fc/cartridge/board/konami-vrc7.cpp index 1f706c00..5d2c02e8 100644 --- a/higan/fc/cartridge/board/konami-vrc7.cpp +++ b/higan/fc/cartridge/board/konami-vrc7.cpp @@ -32,10 +32,6 @@ struct KonamiVRC7 : Board { vrc7.power(); } - auto reset() -> void { - vrc7.reset(); - } - auto serialize(serializer& s) -> void { Board::serialize(s); vrc7.serialize(s); diff --git a/higan/fc/cartridge/board/nes-axrom.cpp b/higan/fc/cartridge/board/nes-axrom.cpp index b773a0c1..4e40a41d 100644 --- a/higan/fc/cartridge/board/nes-axrom.cpp +++ b/higan/fc/cartridge/board/nes-axrom.cpp @@ -30,9 +30,6 @@ struct NES_AxROM : Board { } auto power() -> void { - } - - auto reset() -> void { prgBank = 0x0f; mirrorSelect = 0; } diff --git a/higan/fc/cartridge/board/nes-bnrom.cpp b/higan/fc/cartridge/board/nes-bnrom.cpp index e0163e48..59bbd743 100644 --- a/higan/fc/cartridge/board/nes-bnrom.cpp +++ b/higan/fc/cartridge/board/nes-bnrom.cpp @@ -31,9 +31,6 @@ struct NES_BNROM : Board { } auto power() -> void { - } - - auto reset() -> void { prgBank = 0; } diff --git a/higan/fc/cartridge/board/nes-cnrom.cpp b/higan/fc/cartridge/board/nes-cnrom.cpp index 33163201..0131eb4b 100644 --- a/higan/fc/cartridge/board/nes-cnrom.cpp +++ b/higan/fc/cartridge/board/nes-cnrom.cpp @@ -33,9 +33,6 @@ struct NES_CNROM : Board { } auto power() -> void { - } - - auto reset() -> void { chrBank = 0; } diff --git a/higan/fc/cartridge/board/nes-exrom.cpp b/higan/fc/cartridge/board/nes-exrom.cpp index 02229d8d..0e7ff97e 100644 --- a/higan/fc/cartridge/board/nes-exrom.cpp +++ b/higan/fc/cartridge/board/nes-exrom.cpp @@ -31,10 +31,6 @@ struct NES_ExROM : Board { mmc5.power(); } - auto reset() -> void { - mmc5.reset(); - } - auto serialize(serializer& s) -> void { Board::serialize(s); mmc5.serialize(s); diff --git a/higan/fc/cartridge/board/nes-fxrom.cpp b/higan/fc/cartridge/board/nes-fxrom.cpp index b4a33165..a513857a 100644 --- a/higan/fc/cartridge/board/nes-fxrom.cpp +++ b/higan/fc/cartridge/board/nes-fxrom.cpp @@ -52,9 +52,6 @@ struct NES_FxROM : Board { } auto power() -> void { - } - - auto reset() -> void { prgBank = 0; chrBank[0][0] = 0; chrBank[0][1] = 0; diff --git a/higan/fc/cartridge/board/nes-gxrom.cpp b/higan/fc/cartridge/board/nes-gxrom.cpp index 547d296b..cb9c6a7d 100644 --- a/higan/fc/cartridge/board/nes-gxrom.cpp +++ b/higan/fc/cartridge/board/nes-gxrom.cpp @@ -37,9 +37,6 @@ struct NES_GxROM : Board { } auto power() -> void { - } - - auto reset() -> void { prgBank = 0; chrBank = 0; } diff --git a/higan/fc/cartridge/board/nes-hkrom.cpp b/higan/fc/cartridge/board/nes-hkrom.cpp index 35c1ac1c..14cda41a 100644 --- a/higan/fc/cartridge/board/nes-hkrom.cpp +++ b/higan/fc/cartridge/board/nes-hkrom.cpp @@ -33,10 +33,6 @@ struct NES_HKROM : Board { mmc6.power(); } - auto reset() -> void { - mmc6.reset(); - } - auto serialize(serializer& s) -> void { Board::serialize(s); mmc6.serialize(s); diff --git a/higan/fc/cartridge/board/nes-nrom.cpp b/higan/fc/cartridge/board/nes-nrom.cpp index c352f9a6..ec79351d 100644 --- a/higan/fc/cartridge/board/nes-nrom.cpp +++ b/higan/fc/cartridge/board/nes-nrom.cpp @@ -31,6 +31,9 @@ struct NES_NROM : Board { if(chrram.size) return chrram.write(addr, data); } + auto power() -> void { + } + auto serialize(serializer& s) -> void { Board::serialize(s); } diff --git a/higan/fc/cartridge/board/nes-pxrom.cpp b/higan/fc/cartridge/board/nes-pxrom.cpp index 79dfd755..c41ac0dd 100644 --- a/higan/fc/cartridge/board/nes-pxrom.cpp +++ b/higan/fc/cartridge/board/nes-pxrom.cpp @@ -58,9 +58,6 @@ struct NES_PxROM : Board { } auto power() -> void { - } - - auto reset() -> void { prgBank = 0; chrBank[0][0] = 0; chrBank[0][1] = 0; diff --git a/higan/fc/cartridge/board/nes-sxrom.cpp b/higan/fc/cartridge/board/nes-sxrom.cpp index 85ca378d..abc47ad1 100644 --- a/higan/fc/cartridge/board/nes-sxrom.cpp +++ b/higan/fc/cartridge/board/nes-sxrom.cpp @@ -61,10 +61,6 @@ struct NES_SxROM : Board { mmc1.power(); } - auto reset() -> void { - mmc1.reset(); - } - auto serialize(serializer& s) -> void { Board::serialize(s); mmc1.serialize(s); diff --git a/higan/fc/cartridge/board/nes-txrom.cpp b/higan/fc/cartridge/board/nes-txrom.cpp index c3d81259..784e847f 100644 --- a/higan/fc/cartridge/board/nes-txrom.cpp +++ b/higan/fc/cartridge/board/nes-txrom.cpp @@ -34,10 +34,6 @@ struct NES_TxROM : Board { mmc3.power(); } - auto reset() -> void { - mmc3.reset(); - } - auto serialize(serializer& s) -> void { Board::serialize(s); mmc3.serialize(s); diff --git a/higan/fc/cartridge/board/nes-uxrom.cpp b/higan/fc/cartridge/board/nes-uxrom.cpp index ff4f542c..613c8f28 100644 --- a/higan/fc/cartridge/board/nes-uxrom.cpp +++ b/higan/fc/cartridge/board/nes-uxrom.cpp @@ -33,9 +33,6 @@ struct NES_UxROM : Board { } auto power() -> void { - } - - auto reset() -> void { prgBank = 0; } diff --git a/higan/fc/cartridge/board/sunsoft-5b.cpp b/higan/fc/cartridge/board/sunsoft-5b.cpp index a300798a..5f5d4fb3 100644 --- a/higan/fc/cartridge/board/sunsoft-5b.cpp +++ b/higan/fc/cartridge/board/sunsoft-5b.cpp @@ -14,7 +14,7 @@ struct Sunsoft5B : Board { if(disable) output = 0; } - auto reset() -> void { + auto power() -> void { disable = 1; frequency = 1; volume = 0; @@ -164,13 +164,11 @@ struct Sunsoft5B : Board { } auto power() -> void { - for(signed n : range(16)) { + for(int n : range(16)) { double volume = 1.0 / pow(2, 1.0 / 2 * (15 - n)); dac[n] = volume * 8192.0; } - } - auto reset() -> void { mmuPort = 0; apuPort = 0; @@ -181,9 +179,9 @@ struct Sunsoft5B : Board { irqCounterEnable = 0; irqCounter = 0; - pulse[0].reset(); - pulse[1].reset(); - pulse[2].reset(); + pulse[0].power(); + pulse[1].power(); + pulse[2].power(); } auto serialize(serializer& s) -> void { diff --git a/higan/fc/cartridge/cartridge.cpp b/higan/fc/cartridge/cartridge.cpp index c43a11e8..9bc8b803 100644 --- a/higan/fc/cartridge/cartridge.cpp +++ b/higan/fc/cartridge/cartridge.cpp @@ -45,12 +45,8 @@ auto Cartridge::unload() -> void { } auto Cartridge::power() -> void { - board->power(); -} - -auto Cartridge::reset() -> void { create(Cartridge::Enter, system.colorburst() * 6.0); - board->reset(); + board->power(); } auto Cartridge::readPRG(uint addr) -> uint8 { diff --git a/higan/fc/cartridge/cartridge.hpp b/higan/fc/cartridge/cartridge.hpp index a3676ccd..165f2c5b 100644 --- a/higan/fc/cartridge/cartridge.hpp +++ b/higan/fc/cartridge/cartridge.hpp @@ -15,7 +15,6 @@ struct Cartridge : Thread { auto unload() -> void; auto power() -> void; - auto reset() -> void; auto serialize(serializer&) -> void; diff --git a/higan/fc/cartridge/chip/mmc1.cpp b/higan/fc/cartridge/chip/mmc1.cpp index 92846b95..bd0a73b7 100644 --- a/higan/fc/cartridge/chip/mmc1.cpp +++ b/higan/fc/cartridge/chip/mmc1.cpp @@ -74,9 +74,6 @@ struct MMC1 : Chip { } auto power() -> void { - } - - auto reset() -> void { writedelay = 0; shiftaddr = 0; shiftdata = 0; diff --git a/higan/fc/cartridge/chip/mmc3.cpp b/higan/fc/cartridge/chip/mmc3.cpp index e23b6056..e7049dd3 100644 --- a/higan/fc/cartridge/chip/mmc3.cpp +++ b/higan/fc/cartridge/chip/mmc3.cpp @@ -119,9 +119,6 @@ struct MMC3 : Chip { } auto power() -> void { - } - - auto reset() -> void { chrMode = 0; prgMode = 0; bankSelect = 0; diff --git a/higan/fc/cartridge/chip/mmc5.cpp b/higan/fc/cartridge/chip/mmc5.cpp index 1bddfa69..c48f7bc2 100644 --- a/higan/fc/cartridge/chip/mmc5.cpp +++ b/higan/fc/cartridge/chip/mmc5.cpp @@ -335,9 +335,6 @@ struct MMC5 : Chip { } auto power() -> void { - } - - auto reset() -> void { for(auto& n : exram) n = 0xff; prgMode = 3; diff --git a/higan/fc/cartridge/chip/mmc6.cpp b/higan/fc/cartridge/chip/mmc6.cpp index f21c95d7..b2dff3d4 100644 --- a/higan/fc/cartridge/chip/mmc6.cpp +++ b/higan/fc/cartridge/chip/mmc6.cpp @@ -133,9 +133,6 @@ struct MMC6 : Chip { } auto power() -> void { - } - - auto reset() -> void { chrMode = 0; prgMode = 0; ramEnable = 0; diff --git a/higan/fc/cartridge/chip/vrc1.cpp b/higan/fc/cartridge/chip/vrc1.cpp index 0d6ae0e8..7e1ca3b6 100644 --- a/higan/fc/cartridge/chip/vrc1.cpp +++ b/higan/fc/cartridge/chip/vrc1.cpp @@ -55,9 +55,6 @@ struct VRC1 : Chip { } auto power() -> void { - } - - auto reset() -> void { for(auto& n : prgBank) n = 0; for(auto& n : chrBankLo) n = 0; for(auto& n : chrBankHi) n = 0; diff --git a/higan/fc/cartridge/chip/vrc2.cpp b/higan/fc/cartridge/chip/vrc2.cpp index 54e3644a..85ea6914 100644 --- a/higan/fc/cartridge/chip/vrc2.cpp +++ b/higan/fc/cartridge/chip/vrc2.cpp @@ -85,9 +85,6 @@ struct VRC2 : Chip { } auto power() -> void { - } - - auto reset() -> void { for(auto& n : prgBank) n = 0; for(auto& n : chrBank) n = 0; mirror = 0; diff --git a/higan/fc/cartridge/chip/vrc3.cpp b/higan/fc/cartridge/chip/vrc3.cpp index 60437d54..81e0a68b 100644 --- a/higan/fc/cartridge/chip/vrc3.cpp +++ b/higan/fc/cartridge/chip/vrc3.cpp @@ -55,9 +55,6 @@ struct VRC3 : Chip { } auto power() -> void { - } - - auto reset() -> void { prgBank = 0; irqMode = 0; irqEnable = 0; diff --git a/higan/fc/cartridge/chip/vrc4.cpp b/higan/fc/cartridge/chip/vrc4.cpp index d9488ec8..fba7b431 100644 --- a/higan/fc/cartridge/chip/vrc4.cpp +++ b/higan/fc/cartridge/chip/vrc4.cpp @@ -126,9 +126,6 @@ struct VRC4 : Chip { } auto power() -> void { - } - - auto reset() -> void { prgMode = 0; for(auto& n : prgBank) n = 0; mirror = 0; diff --git a/higan/fc/cartridge/chip/vrc6.cpp b/higan/fc/cartridge/chip/vrc6.cpp index 0b23a429..a0123ab4 100644 --- a/higan/fc/cartridge/chip/vrc6.cpp +++ b/higan/fc/cartridge/chip/vrc6.cpp @@ -227,9 +227,6 @@ struct VRC6 : Chip { } auto power() -> void { - } - - auto reset() -> void { prgBank[0] = 0; prgBank[1] = 0; chrBank[0] = 0; diff --git a/higan/fc/cartridge/chip/vrc7.cpp b/higan/fc/cartridge/chip/vrc7.cpp index 5a5e38af..4903d13f 100644 --- a/higan/fc/cartridge/chip/vrc7.cpp +++ b/higan/fc/cartridge/chip/vrc7.cpp @@ -99,9 +99,6 @@ struct VRC7 : Chip { } auto power() -> void { - } - - auto reset() -> void { for(auto& n : prgBank) n = 0; for(auto& n : chrBank) n = 0; mirror = 0; diff --git a/higan/fc/cpu/cpu.cpp b/higan/fc/cpu/cpu.cpp index c39000fa..780a7854 100644 --- a/higan/fc/cpu/cpu.cpp +++ b/higan/fc/cpu/cpu.cpp @@ -26,17 +26,13 @@ auto CPU::step(uint clocks) -> void { auto CPU::power() -> void { R6502::power(); + create(CPU::Enter, system.colorburst() * 6.0); for(auto addr : range(0x0800)) ram[addr] = 0xff; ram[0x0008] = 0xf7; ram[0x0009] = 0xef; ram[0x000a] = 0xdf; ram[0x000f] = 0xbf; -} - -auto CPU::reset() -> void { - R6502::reset(); - create(CPU::Enter, system.colorburst() * 6.0); regs.pc = bus.read(0xfffc) << 0; regs.pc |= bus.read(0xfffd) << 8; diff --git a/higan/fc/cpu/cpu.hpp b/higan/fc/cpu/cpu.hpp index a530fa7e..5382dc17 100644 --- a/higan/fc/cpu/cpu.hpp +++ b/higan/fc/cpu/cpu.hpp @@ -4,7 +4,6 @@ struct CPU : Processor::R6502, Thread { auto step(uint clocks) -> void; auto power() -> void; - auto reset() -> void; //memory.cpp auto readRAM(uint11 addr) -> uint8; diff --git a/higan/fc/interface/interface.cpp b/higan/fc/interface/interface.cpp index 6a280eeb..bf2e7e56 100644 --- a/higan/fc/interface/interface.cpp +++ b/higan/fc/interface/interface.cpp @@ -8,7 +8,6 @@ Interface::Interface() { information.manufacturer = "Nintendo"; information.name = "Famicom"; information.overscan = true; - information.resettable = true; information.capability.states = true; information.capability.cheats = true; @@ -151,10 +150,6 @@ auto Interface::power() -> void { system.power(); } -auto Interface::reset() -> void { - system.reset(); -} - auto Interface::run() -> void { system.run(); } diff --git a/higan/fc/interface/interface.hpp b/higan/fc/interface/interface.hpp index 6468de3b..060fffe7 100644 --- a/higan/fc/interface/interface.hpp +++ b/higan/fc/interface/interface.hpp @@ -42,7 +42,6 @@ struct Interface : Emulator::Interface { auto connect(uint port, uint device) -> void override; auto power() -> void override; - auto reset() -> void override; auto run() -> void override; auto serialize() -> serializer override; diff --git a/higan/fc/ppu/ppu.cpp b/higan/fc/ppu/ppu.cpp index 299ac4bb..69faf451 100644 --- a/higan/fc/ppu/ppu.cpp +++ b/higan/fc/ppu/ppu.cpp @@ -53,9 +53,6 @@ auto PPU::refresh() -> void { } auto PPU::power() -> void { -} - -auto PPU::reset() -> void { create(PPU::Enter, system.colorburst() * 6.0); memory::fill(&io, sizeof(IO)); diff --git a/higan/fc/ppu/ppu.hpp b/higan/fc/ppu/ppu.hpp index 21b73417..1e3e7040 100644 --- a/higan/fc/ppu/ppu.hpp +++ b/higan/fc/ppu/ppu.hpp @@ -8,7 +8,6 @@ struct PPU : Thread { auto refresh() -> void; auto power() -> void; - auto reset() -> void; //memory.cpp auto readCIRAM(uint11 addr) -> uint8; diff --git a/higan/fc/system/system.cpp b/higan/fc/system/system.cpp index 4df6a364..e0e8e676 100644 --- a/higan/fc/system/system.cpp +++ b/higan/fc/system/system.cpp @@ -49,14 +49,6 @@ auto System::unload() -> void { } auto System::power() -> void { - cartridge.power(); - cpu.power(); - apu.power(); - ppu.power(); - reset(); -} - -auto System::reset() -> void { Emulator::video.reset(); Emulator::video.setInterface(interface); configureVideoPalette(); @@ -66,10 +58,10 @@ auto System::reset() -> void { Emulator::audio.setInterface(interface); scheduler.reset(); - cartridge.reset(); - cpu.reset(); - apu.reset(); - ppu.reset(); + cartridge.power(); + cpu.power(); + apu.power(); + ppu.power(); scheduler.primary(cpu); peripherals.reset(); } diff --git a/higan/fc/system/system.hpp b/higan/fc/system/system.hpp index b3ae2ee8..1635ca06 100644 --- a/higan/fc/system/system.hpp +++ b/higan/fc/system/system.hpp @@ -9,7 +9,6 @@ struct System { auto save() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto init() -> void; auto term() -> void; diff --git a/higan/gb/interface/game-boy-color.cpp b/higan/gb/interface/game-boy-color.cpp new file mode 100644 index 00000000..fd5c0d91 --- /dev/null +++ b/higan/gb/interface/game-boy-color.cpp @@ -0,0 +1,149 @@ +GameBoyColorInterface::GameBoyColorInterface() { + information.manufacturer = "Nintendo"; + information.name = "Game Boy Color"; + information.overscan = false; + + information.capability.states = true; + information.capability.cheats = true; + + media.append({ID::GameBoyColor, "Game Boy Color", "gb"}); + + Port hardwarePort{ID::Port::Hardware, "Hardware"}; + + { Device device{ID::Device::Controls, "Controls"}; + device.inputs.append({0, "Up" }); + device.inputs.append({0, "Down" }); + device.inputs.append({0, "Left" }); + device.inputs.append({0, "Right" }); + device.inputs.append({0, "B" }); + device.inputs.append({0, "A" }); + device.inputs.append({0, "Select"}); + device.inputs.append({0, "Start" }); + hardwarePort.devices.append(device); + } + + ports.append(move(hardwarePort)); +} + +auto GameBoyColorInterface::manifest() -> string { + return cartridge.manifest(); +} + +auto GameBoyColorInterface::title() -> string { + return cartridge.title(); +} + +auto GameBoyColorInterface::videoSize() -> VideoSize { + return {160, 144}; +} + +auto GameBoyColorInterface::videoSize(uint width, uint height, bool arc) -> VideoSize { + uint w = 160; + uint h = 144; + uint m = min(width / w, height / h); + return {w * m, h * m}; +} + +auto GameBoyColorInterface::videoFrequency() -> double { + return 4194304.0 / (154.0 * 456.0); +} + +auto GameBoyColorInterface::videoColors() -> uint32 { + return 1 << 15; +} + +auto GameBoyColorInterface::videoColor(uint32 color) -> uint64 { + uint r = color.bits( 0, 4); + uint g = color.bits( 5, 9); + uint b = color.bits(10,14); + + uint64_t R = image::normalize(r, 5, 16); + uint64_t G = image::normalize(g, 5, 16); + uint64_t B = image::normalize(b, 5, 16); + + if(settings.colorEmulation) { + R = (r * 26 + g * 4 + b * 2); + G = ( g * 24 + b * 8); + B = (r * 6 + g * 4 + b * 22); + R = image::normalize(min(960, R), 10, 16); + G = image::normalize(min(960, G), 10, 16); + B = image::normalize(min(960, B), 10, 16); + } + + return R << 32 | G << 16 | B << 0; +} + +auto GameBoyColorInterface::audioFrequency() -> double { + return 4194304.0 / 2.0; +} + +auto GameBoyColorInterface::loaded() -> bool { + return system.loaded(); +} + +auto GameBoyColorInterface::sha256() -> string { + return cartridge.sha256(); +} + +auto GameBoyColorInterface::load(uint id) -> bool { + if(id == ID::GameBoyColor) return system.load(this, System::Revision::GameBoyColor); + return false; +} + +auto GameBoyColorInterface::save() -> void { + system.save(); +} + +auto GameBoyColorInterface::unload() -> void { + save(); + system.unload(); +} + +auto GameBoyColorInterface::power() -> void { + system.power(); +} + +auto GameBoyColorInterface::run() -> void { + system.run(); +} + +auto GameBoyColorInterface::serialize() -> serializer { + system.runToSave(); + return system.serialize(); +} + +auto GameBoyColorInterface::unserialize(serializer& s) -> bool { + return system.unserialize(s); +} + +auto GameBoyColorInterface::cheatSet(const string_vector& list) -> void { + cheat.assign(list); +} + +auto GameBoyColorInterface::cap(const string& name) -> bool { + if(name == "Blur Emulation") return true; + if(name == "Color Emulation") return true; + return false; +} + +auto GameBoyColorInterface::get(const string& name) -> any { + if(name == "Blur Emulation") return settings.blurEmulation; + if(name == "Color Emulation") return settings.colorEmulation; + return {}; +} + +auto GameBoyColorInterface::set(const string& name, const any& value) -> bool { + if(name == "Blur Emulation" && value.is()) { + settings.blurEmulation = value.get(); + system.configureVideoEffects(); + return true; + } + + if(name == "Color Emulation" && value.is()) { + settings.colorEmulation = value.get(); + system.configureVideoPalette(); + return true; + } + + return false; +} diff --git a/higan/gb/interface/game-boy.cpp b/higan/gb/interface/game-boy.cpp new file mode 100644 index 00000000..0bb3061b --- /dev/null +++ b/higan/gb/interface/game-boy.cpp @@ -0,0 +1,164 @@ +GameBoyInterface::GameBoyInterface() { + information.manufacturer = "Nintendo"; + information.name = "Game Boy"; + information.overscan = false; + + information.capability.states = true; + information.capability.cheats = true; + + media.append({ID::GameBoy, "Game Boy", "gb"}); + + Port hardwarePort{ID::Port::Hardware, "Hardware"}; + + { Device device{ID::Device::Controls, "Controls"}; + device.inputs.append({0, "Up" }); + device.inputs.append({0, "Down" }); + device.inputs.append({0, "Left" }); + device.inputs.append({0, "Right" }); + device.inputs.append({0, "B" }); + device.inputs.append({0, "A" }); + device.inputs.append({0, "Select"}); + device.inputs.append({0, "Start" }); + hardwarePort.devices.append(device); + } + + ports.append(move(hardwarePort)); +} + +auto GameBoyInterface::manifest() -> string { + return cartridge.manifest(); +} + +auto GameBoyInterface::title() -> string { + return cartridge.title(); +} + +auto GameBoyInterface::videoSize() -> VideoSize { + return {160, 144}; +} + +auto GameBoyInterface::videoSize(uint width, uint height, bool arc) -> VideoSize { + uint w = 160; + uint h = 144; + uint m = min(width / w, height / h); + return {w * m, h * m}; +} + +auto GameBoyInterface::videoFrequency() -> double { + return 4194304.0 / (154.0 * 456.0); +} + +auto GameBoyInterface::videoColors() -> uint32 { + return 1 << 2; +} + +auto GameBoyInterface::videoColor(uint32 color) -> uint64 { + if(!settings.colorEmulation) { + uint64 L = image::normalize(3 - color, 2, 16); + return L << 32 | L << 16 | L << 0; + } else { + #define DMG_PALETTE_GREEN + //#define DMG_PALETTE_YELLOW + //#define DMG_PALETTE_WHITE + + const uint16 monochrome[4][3] = { + #if defined(DMG_PALETTE_GREEN) + {0xaeae, 0xd9d9, 0x2727}, + {0x5858, 0xa0a0, 0x2828}, + {0x2020, 0x6262, 0x2929}, + {0x1a1a, 0x4545, 0x2a2a}, + #elif defined(DMG_PALETTE_YELLOW) + {0xffff, 0xf7f7, 0x7b7b}, + {0xb5b5, 0xaeae, 0x4a4a}, + {0x6b6b, 0x6969, 0x3131}, + {0x2121, 0x2020, 0x1010}, + #elif defined(DMG_PALETTE_WHITE) + {0xffff, 0xffff, 0xffff}, + {0xaaaa, 0xaaaa, 0xaaaa}, + {0x5555, 0x5555, 0x5555}, + {0x0000, 0x0000, 0x0000}, + #endif + }; + + uint64 R = monochrome[color][0]; + uint64 G = monochrome[color][1]; + uint64 B = monochrome[color][2]; + + return R << 32 | G << 16 | B << 0; + } +} + +auto GameBoyInterface::audioFrequency() -> double { + return 4194304.0 / 2.0; +} + +auto GameBoyInterface::loaded() -> bool { + return system.loaded(); +} + +auto GameBoyInterface::sha256() -> string { + return cartridge.sha256(); +} + +auto GameBoyInterface::load(uint id) -> bool { + if(id == ID::GameBoy) return system.load(this, System::Revision::GameBoy); + return false; +} + +auto GameBoyInterface::save() -> void { + system.save(); +} + +auto GameBoyInterface::unload() -> void { + save(); + system.unload(); +} + +auto GameBoyInterface::power() -> void { + system.power(); +} + +auto GameBoyInterface::run() -> void { + system.run(); +} + +auto GameBoyInterface::serialize() -> serializer { + system.runToSave(); + return system.serialize(); +} + +auto GameBoyInterface::unserialize(serializer& s) -> bool { + return system.unserialize(s); +} + +auto GameBoyInterface::cheatSet(const string_vector& list) -> void { + cheat.assign(list); +} + +auto GameBoyInterface::cap(const string& name) -> bool { + if(name == "Blur Emulation") return true; + if(name == "Color Emulation") return true; + return false; +} + +auto GameBoyInterface::get(const string& name) -> any { + if(name == "Blur Emulation") return settings.blurEmulation; + if(name == "Color Emulation") return settings.colorEmulation; + return {}; +} + +auto GameBoyInterface::set(const string& name, const any& value) -> bool { + if(name == "Blur Emulation" && value.is()) { + settings.blurEmulation = value.get(); + system.configureVideoEffects(); + return true; + } + + if(name == "Color Emulation" && value.is()) { + settings.colorEmulation = value.get(); + system.configureVideoPalette(); + return true; + } + + return false; +} diff --git a/higan/gb/interface/interface.cpp b/higan/gb/interface/interface.cpp index fc3756a9..c9e6b156 100644 --- a/higan/gb/interface/interface.cpp +++ b/higan/gb/interface/interface.cpp @@ -3,213 +3,7 @@ namespace GameBoy { Settings settings; - -Interface::Interface() { - hook = nullptr; - - information.manufacturer = "Nintendo"; - information.name = "Game Boy"; - information.overscan = false; - information.resettable = false; - - information.capability.states = true; - information.capability.cheats = true; - - media.append({ID::GameBoy, "Game Boy", "gb" }); - media.append({ID::GameBoyColor, "Game Boy Color", "gbc"}); - - Port hardwarePort{ID::Port::Hardware, "Hardware"}; - - { Device device{ID::Device::Controls, "Controls"}; - device.inputs.append({0, "Up" }); - device.inputs.append({0, "Down" }); - device.inputs.append({0, "Left" }); - device.inputs.append({0, "Right" }); - device.inputs.append({0, "B" }); - device.inputs.append({0, "A" }); - device.inputs.append({0, "Select"}); - device.inputs.append({0, "Start" }); - hardwarePort.devices.append(device); - } - - ports.append(move(hardwarePort)); -} - -auto Interface::manifest() -> string { - return cartridge.manifest(); -} - -auto Interface::title() -> string { - return cartridge.title(); -} - -auto Interface::videoSize() -> VideoSize { - return {160, 144}; -} - -auto Interface::videoSize(uint width, uint height, bool arc) -> VideoSize { - uint w = 160; - uint h = 144; - uint m = min(width / w, height / h); - return {w * m, h * m}; -} - -auto Interface::videoFrequency() -> double { - return 4194304.0 / (154.0 * 456.0); -} - -auto Interface::videoColors() -> uint32 { - return !system.cgb() ? 1 << 2 : 1 << 15; -} - -auto Interface::videoColor(uint32 color) -> uint64 { - if(!system.cgb()) { - if(!settings.colorEmulation) { - uint64 L = image::normalize(3 - color, 2, 16); - return L << 32 | L << 16 | L << 0; - } else { - #define DMG_PALETTE_GREEN - //#define DMG_PALETTE_YELLOW - //#define DMG_PALETTE_WHITE - - const uint16 monochrome[4][3] = { - #if defined(DMG_PALETTE_GREEN) - {0xaeae, 0xd9d9, 0x2727}, - {0x5858, 0xa0a0, 0x2828}, - {0x2020, 0x6262, 0x2929}, - {0x1a1a, 0x4545, 0x2a2a}, - #elif defined(DMG_PALETTE_YELLOW) - {0xffff, 0xf7f7, 0x7b7b}, - {0xb5b5, 0xaeae, 0x4a4a}, - {0x6b6b, 0x6969, 0x3131}, - {0x2121, 0x2020, 0x1010}, - #elif defined(DMG_PALETTE_WHITE) - {0xffff, 0xffff, 0xffff}, - {0xaaaa, 0xaaaa, 0xaaaa}, - {0x5555, 0x5555, 0x5555}, - {0x0000, 0x0000, 0x0000}, - #endif - }; - - uint64 R = monochrome[color][0]; - uint64 G = monochrome[color][1]; - uint64 B = monochrome[color][2]; - - return R << 32 | G << 16 | B << 0; - } - } else { - uint r = color.bits( 0, 4); - uint g = color.bits( 5, 9); - uint b = color.bits(10,14); - - uint64_t R = image::normalize(r, 5, 16); - uint64_t G = image::normalize(g, 5, 16); - uint64_t B = image::normalize(b, 5, 16); - - if(settings.colorEmulation) { - R = (r * 26 + g * 4 + b * 2); - G = ( g * 24 + b * 8); - B = (r * 6 + g * 4 + b * 22); - R = image::normalize(min(960, R), 10, 16); - G = image::normalize(min(960, G), 10, 16); - B = image::normalize(min(960, B), 10, 16); - } - - return R << 32 | G << 16 | B << 0; - } -} - -auto Interface::audioFrequency() -> double { - return 4194304.0 / 2.0; -} - -auto Interface::loaded() -> bool { - return system.loaded(); -} - -auto Interface::sha256() -> string { - return cartridge.sha256(); -} - -auto Interface::load(uint id) -> bool { - if(id == ID::GameBoy) return system.load(this, System::Revision::GameBoy); - if(id == ID::SuperGameBoy) return system.load(this, System::Revision::SuperGameBoy); - if(id == ID::GameBoyColor) return system.load(this, System::Revision::GameBoyColor); - return false; -} - -auto Interface::save() -> void { - system.save(); -} - -auto Interface::unload() -> void { - save(); - system.unload(); -} - -auto Interface::power() -> void { - system.power(); -} - -auto Interface::reset() -> void { - system.power(); -} - -auto Interface::run() -> void { - system.run(); -} - -auto Interface::serialize() -> serializer { - system.runToSave(); - return system.serialize(); -} - -auto Interface::unserialize(serializer& s) -> bool { - return system.unserialize(s); -} - -auto Interface::cheatSet(const string_vector& list) -> void { - cheat.assign(list); -} - -auto Interface::lcdScanline() -> void { - if(hook) hook->lcdScanline(); -} - -auto Interface::lcdOutput(uint2 color) -> void { - if(hook) hook->lcdOutput(color); -} - -auto Interface::joypWrite(bool p15, bool p14) -> void { - if(hook) hook->joypWrite(p15, p14); -} - -auto Interface::cap(const string& name) -> bool { - if(name == "Blur Emulation") return true; - if(name == "Color Emulation") return true; - return false; -} - -auto Interface::get(const string& name) -> any { - if(name == "Blur Emulation") return settings.blurEmulation; - if(name == "Color Emulation") return settings.colorEmulation; - return {}; -} - -auto Interface::set(const string& name, const any& value) -> bool { - if(name == "Blur Emulation" && value.is()) { - settings.blurEmulation = value.get(); - system.configureVideoEffects(); - return true; - } - - if(name == "Color Emulation" && value.is()) { - settings.colorEmulation = value.get(); - system.configureVideoPalette(); - return true; - } - - return false; -} +#include "game-boy.cpp" +#include "game-boy-color.cpp" } diff --git a/higan/gb/interface/interface.hpp b/higan/gb/interface/interface.hpp index 2be35689..0e9db93b 100644 --- a/higan/gb/interface/interface.hpp +++ b/higan/gb/interface/interface.hpp @@ -17,10 +17,10 @@ struct ID { };}; }; -struct Interface : Emulator::Interface { +struct GameBoyInterface : Emulator::Interface { using Emulator::Interface::load; - Interface(); + GameBoyInterface(); auto manifest() -> string override; auto title() -> string override; @@ -40,7 +40,6 @@ struct Interface : Emulator::Interface { auto unload() -> void override; auto power() -> void override; - auto reset() -> void override; auto run() -> void override; auto serialize() -> serializer override; @@ -51,7 +50,45 @@ struct Interface : Emulator::Interface { auto cap(const string& name) -> bool override; auto get(const string& name) -> any override; auto set(const string& name, const any& value) -> bool override; +}; +struct GameBoyColorInterface : Emulator::Interface { + using Emulator::Interface::load; + + GameBoyColorInterface(); + + auto manifest() -> string override; + auto title() -> string override; + + auto videoSize() -> VideoSize override; + auto videoSize(uint width, uint height, bool arc) -> VideoSize override; + auto videoFrequency() -> double override; + auto videoColors() -> uint32 override; + auto videoColor(uint32 color) -> uint64 override; + + auto audioFrequency() -> double override; + + auto loaded() -> bool override; + auto sha256() -> string override; + auto load(uint id) -> bool override; + auto save() -> void override; + auto unload() -> void override; + + auto power() -> void override; + auto run() -> void override; + + auto serialize() -> serializer override; + auto unserialize(serializer&) -> bool override; + + auto cheatSet(const string_vector&) -> void override; + + auto cap(const string& name) -> bool override; + auto get(const string& name) -> any override; + auto set(const string& name, const any& value) -> bool override; +}; + +/* +struct Interface : Emulator::Interface { //Super Game Boy bindings struct Hook { virtual auto lcdScanline() -> void {} @@ -64,6 +101,7 @@ struct Interface : Emulator::Interface { auto lcdOutput(uint2 color) -> void; auto joypWrite(bool p15, bool p14) -> void; }; +*/ struct Settings { bool blurEmulation = true; diff --git a/higan/gba/interface/interface.cpp b/higan/gba/interface/interface.cpp index 4d3b67bb..6084b4c1 100644 --- a/higan/gba/interface/interface.cpp +++ b/higan/gba/interface/interface.cpp @@ -8,7 +8,6 @@ Interface::Interface() { information.manufacturer = "Nintendo"; information.name = "Game Boy Advance"; information.overscan = false; - information.resettable = false; information.capability.states = true; information.capability.cheats = false; @@ -109,10 +108,6 @@ auto Interface::power() -> void { system.power(); } -auto Interface::reset() -> void { - system.power(); -} - auto Interface::run() -> void { system.run(); } diff --git a/higan/gba/interface/interface.hpp b/higan/gba/interface/interface.hpp index ad29c1cf..b55ac1c4 100644 --- a/higan/gba/interface/interface.hpp +++ b/higan/gba/interface/interface.hpp @@ -37,7 +37,6 @@ struct Interface : Emulator::Interface { auto unload() -> void override; auto power() -> void override; - auto reset() -> void override; auto run() -> void override; auto serialize() -> serializer override; diff --git a/higan/md/cartridge/cartridge.cpp b/higan/md/cartridge/cartridge.cpp index 1607a780..fcf57089 100644 --- a/higan/md/cartridge/cartridge.cpp +++ b/higan/md/cartridge/cartridge.cpp @@ -67,9 +67,6 @@ auto Cartridge::unload() -> void { auto Cartridge::power() -> void { } -auto Cartridge::reset() -> void { -} - auto Cartridge::read(uint24 addr) -> uint16 { uint16 data = rom.data[addr + 0 & rom.mask] << 8; return data | rom.data[addr + 1 & rom.mask] << 0; diff --git a/higan/md/cartridge/cartridge.hpp b/higan/md/cartridge/cartridge.hpp index 08323503..a8001d4d 100644 --- a/higan/md/cartridge/cartridge.hpp +++ b/higan/md/cartridge/cartridge.hpp @@ -8,7 +8,6 @@ struct Cartridge { auto save() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto read(uint24 addr) -> uint16; auto write(uint24 addr, uint16 data) -> void; diff --git a/higan/md/cpu/cpu.cpp b/higan/md/cpu/cpu.cpp index 4dd9d0d5..781f0183 100644 --- a/higan/md/cpu/cpu.cpp +++ b/higan/md/cpu/cpu.cpp @@ -73,10 +73,6 @@ auto CPU::lower(Interrupt interrupt) -> void { auto CPU::power() -> void { M68K::bus = &busCPU; M68K::power(); -} - -auto CPU::reset() -> void { - M68K::reset(); create(CPU::Enter, system.colorburst() * 15.0 / 7.0); memory::fill(&state, sizeof(State)); diff --git a/higan/md/cpu/cpu.hpp b/higan/md/cpu/cpu.hpp index 1ed82998..155b3e52 100644 --- a/higan/md/cpu/cpu.hpp +++ b/higan/md/cpu/cpu.hpp @@ -18,7 +18,6 @@ struct CPU : Processor::M68K, Thread { auto lower(Interrupt) -> void; auto power() -> void; - auto reset() -> void; vector peripherals; diff --git a/higan/md/interface/interface.cpp b/higan/md/interface/interface.cpp index eb234962..b0d3559d 100644 --- a/higan/md/interface/interface.cpp +++ b/higan/md/interface/interface.cpp @@ -8,7 +8,6 @@ Interface::Interface() { information.manufacturer = "Sega"; information.name = "Mega Drive"; information.overscan = true; - information.resettable = true; information.capability.states = false; information.capability.cheats = false; @@ -113,10 +112,6 @@ auto Interface::power() -> void { system.power(); } -auto Interface::reset() -> void { - system.reset(); -} - auto Interface::run() -> void { system.run(); } diff --git a/higan/md/interface/interface.hpp b/higan/md/interface/interface.hpp index 586b533f..e4a4839a 100644 --- a/higan/md/interface/interface.hpp +++ b/higan/md/interface/interface.hpp @@ -41,7 +41,6 @@ struct Interface : Emulator::Interface { auto connect(uint port, uint device) -> void override; auto power() -> void override; - auto reset() -> void override; auto run() -> void override; auto serialize() -> serializer override; diff --git a/higan/md/psg/psg.cpp b/higan/md/psg/psg.cpp index 06cf78f0..3af5686d 100644 --- a/higan/md/psg/psg.cpp +++ b/higan/md/psg/psg.cpp @@ -19,9 +19,6 @@ auto PSG::step(uint clocks) -> void { } auto PSG::power() -> void { -} - -auto PSG::reset() -> void { create(PSG::Enter, 52'000); //system.colorburst()); stream = Emulator::audio.createStream(2, 52'000.0); } diff --git a/higan/md/psg/psg.hpp b/higan/md/psg/psg.hpp index 89ba7388..9b11454b 100644 --- a/higan/md/psg/psg.hpp +++ b/higan/md/psg/psg.hpp @@ -8,7 +8,6 @@ struct PSG : Thread { auto step(uint clocks) -> void; auto power() -> void; - auto reset() -> void; }; extern PSG psg; diff --git a/higan/md/system/system.cpp b/higan/md/system/system.cpp index c03d5437..2148a703 100644 --- a/higan/md/system/system.cpp +++ b/higan/md/system/system.cpp @@ -35,16 +35,6 @@ auto System::unload() -> void { } auto System::power() -> void { - cartridge.power(); - cpu.power(); - apu.power(); - vdp.power(); - psg.power(); - ym2612.power(); - reset(); -} - -auto System::reset() -> void { Emulator::video.reset(); Emulator::video.setInterface(interface); Emulator::video.setPalette(); @@ -53,12 +43,12 @@ auto System::reset() -> void { Emulator::audio.setInterface(interface); scheduler.reset(); - cartridge.reset(); - cpu.reset(); + cartridge.power(); + cpu.power(); apu.power(); - vdp.reset(); - psg.reset(); - ym2612.reset(); + vdp.power(); + psg.power(); + ym2612.power(); scheduler.primary(cpu); peripherals.reset(); diff --git a/higan/md/system/system.hpp b/higan/md/system/system.hpp index 91362a60..1acee012 100644 --- a/higan/md/system/system.hpp +++ b/higan/md/system/system.hpp @@ -8,7 +8,6 @@ struct System { auto save() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; private: Emulator::Interface* interface = nullptr; diff --git a/higan/md/vdp/background.cpp b/higan/md/vdp/background.cpp index 8c683a41..47f12fc7 100644 --- a/higan/md/vdp/background.cpp +++ b/higan/md/vdp/background.cpp @@ -77,9 +77,6 @@ auto VDP::Background::run(uint x, uint y) -> void { } auto VDP::Background::power() -> void { -} - -auto VDP::Background::reset() -> void { memory::fill(&io, sizeof(IO)); memory::fill(&state, sizeof(State)); } diff --git a/higan/md/vdp/sprite.cpp b/higan/md/vdp/sprite.cpp index 18e364d9..7743379e 100644 --- a/higan/md/vdp/sprite.cpp +++ b/higan/md/vdp/sprite.cpp @@ -83,8 +83,5 @@ auto VDP::Sprite::run(uint x, uint y) -> void { } auto VDP::Sprite::power() -> void { -} - -auto VDP::Sprite::reset() -> void { memory::fill(&io, sizeof(IO)); } diff --git a/higan/md/vdp/vdp.cpp b/higan/md/vdp/vdp.cpp index 5ebf7340..bd44bb15 100644 --- a/higan/md/vdp/vdp.cpp +++ b/higan/md/vdp/vdp.cpp @@ -51,22 +51,15 @@ auto VDP::refresh() -> void { } auto VDP::power() -> void { + create(VDP::Enter, system.colorburst() * 15.0 / 2.0); + + memory::fill(&io, sizeof(IO)); + memory::fill(&state, sizeof(State)); + planeA.power(); window.power(); planeB.power(); sprite.power(); } -auto VDP::reset() -> void { - create(VDP::Enter, system.colorburst() * 15.0 / 2.0); - - memory::fill(&io, sizeof(IO)); - memory::fill(&state, sizeof(State)); - - planeA.reset(); - window.reset(); - planeB.reset(); - sprite.reset(); -} - } diff --git a/higan/md/vdp/vdp.hpp b/higan/md/vdp/vdp.hpp index 8eb1ec33..c1169cb6 100644 --- a/higan/md/vdp/vdp.hpp +++ b/higan/md/vdp/vdp.hpp @@ -7,7 +7,6 @@ struct VDP : Thread { auto refresh() -> void; auto power() -> void; - auto reset() -> void; //io.cpp auto read(uint24 addr) -> uint16; @@ -47,7 +46,6 @@ struct VDP : Thread { auto run(uint x, uint y) -> void; auto power() -> void; - auto reset() -> void; struct IO { uint15 nametableAddress; @@ -87,7 +85,6 @@ struct VDP : Thread { auto run(uint x, uint y) -> void; auto power() -> void; - auto reset() -> void; struct IO { uint15 attributeAddress; diff --git a/higan/md/ym2612/ym2612.cpp b/higan/md/ym2612/ym2612.cpp index 356130fa..acfb3029 100644 --- a/higan/md/ym2612/ym2612.cpp +++ b/higan/md/ym2612/ym2612.cpp @@ -18,9 +18,6 @@ auto YM2612::step(uint clocks) -> void { } auto YM2612::power() -> void { -} - -auto YM2612::reset() -> void { create(YM2612::Enter, system.colorburst() * 15.0 / 7.0); } diff --git a/higan/md/ym2612/ym2612.hpp b/higan/md/ym2612/ym2612.hpp index e77161b8..f15eb4be 100644 --- a/higan/md/ym2612/ym2612.hpp +++ b/higan/md/ym2612/ym2612.hpp @@ -6,7 +6,6 @@ struct YM2612 : Thread { auto step(uint clocks) -> void; auto power() -> void; - auto reset() -> void; }; extern YM2612 ym2612; diff --git a/higan/ms/interface/game-gear.cpp b/higan/ms/interface/game-gear.cpp index d0dd1d3a..e0730d79 100644 --- a/higan/ms/interface/game-gear.cpp +++ b/higan/ms/interface/game-gear.cpp @@ -2,7 +2,6 @@ GameGearInterface::GameGearInterface() { information.manufacturer = "Sega"; information.name = "Game Gear"; information.overscan = false; - information.resettable = false; information.capability.states = false; information.capability.cheats = false; diff --git a/higan/ms/interface/master-system.cpp b/higan/ms/interface/master-system.cpp index 865e5ffe..18363eb6 100644 --- a/higan/ms/interface/master-system.cpp +++ b/higan/ms/interface/master-system.cpp @@ -2,7 +2,6 @@ MasterSystemInterface::MasterSystemInterface() { information.manufacturer = "Sega"; information.name = "Master System"; information.overscan = true; - information.resettable = false; information.capability.states = false; information.capability.cheats = false; diff --git a/higan/pce/interface/interface.cpp b/higan/pce/interface/interface.cpp index 9b1f4150..a7479903 100644 --- a/higan/pce/interface/interface.cpp +++ b/higan/pce/interface/interface.cpp @@ -8,7 +8,6 @@ Interface::Interface() { information.manufacturer = "NEC"; information.name = "PC Engine"; information.overscan = true; - information.resettable = false; information.capability.states = false; information.capability.cheats = false; diff --git a/higan/pce/vdc/vdc.cpp b/higan/pce/vdc/vdc.cpp index cdf6c094..d763827b 100644 --- a/higan/pce/vdc/vdc.cpp +++ b/higan/pce/vdc/vdc.cpp @@ -52,7 +52,7 @@ auto VDC::main() -> void { step(vce.clock); } - if(vce.vclock == io.lineCoincidence - (66 - vce.vstart)) { + if(vce.vclock == io.lineCoincidence - (65 - vce.vstart)) { irq.raise(IRQ::Line::LineCoincidence); } @@ -70,7 +70,7 @@ auto VDC::scanline() -> void { if(vce.clock == 4) vce.hstart += 0; vce.vclock++; - if(vce.vclock >= vce.vstart) vce.voffset++; + if(vce.vclock > vce.vstart) vce.voffset++; if(vce.vclock == 262) { frame(); @@ -87,7 +87,7 @@ auto VDC::frame() -> void { vce.vclock = 0; vce.voffset = 0; - vce.vstart = vce.verticalDisplayStart - 2; + vce.vstart = max((uint8)2, vce.verticalDisplayStart) - 2; vce.vlength = min(242, vce.verticalDisplayLength + 1); } diff --git a/higan/processor/gsu/gsu.cpp b/higan/processor/gsu/gsu.cpp index 49199c66..54ccc366 100644 --- a/higan/processor/gsu/gsu.cpp +++ b/higan/processor/gsu/gsu.cpp @@ -13,9 +13,6 @@ namespace Processor { #include "disassembler.cpp" auto GSU::power() -> void { -} - -auto GSU::reset() -> void { for(auto& r : regs.r) { r.data = 0x0000; r.modified = false; diff --git a/higan/processor/gsu/gsu.hpp b/higan/processor/gsu/gsu.hpp index 6023d948..a5cf7c5b 100644 --- a/higan/processor/gsu/gsu.hpp +++ b/higan/processor/gsu/gsu.hpp @@ -25,7 +25,6 @@ struct GSU { //gsu.cpp auto power() -> void; - auto reset() -> void; //instructions.cpp auto op_add_adc(uint n); diff --git a/higan/processor/m68k/instruction.cpp b/higan/processor/m68k/instruction.cpp index 49fdf2c8..9f7e7409 100644 --- a/higan/processor/m68k/instruction.cpp +++ b/higan/processor/m68k/instruction.cpp @@ -1,15 +1,4 @@ auto M68K::instruction() -> void { - instructionsExecuted++; - - #if 0 - if(instructionsExecuted >= 10000010) while(true) step(1); - if(instructionsExecuted >= 10000000) { - print(disassembleRegisters(), "\n"); - print(disassemble(r.pc), "\n"); - print("\n"); - } - #endif - opcode = readPC(); return instructionTable[opcode](); } diff --git a/higan/processor/m68k/m68k.cpp b/higan/processor/m68k/m68k.cpp index 41c3874a..87d89446 100644 --- a/higan/processor/m68k/m68k.cpp +++ b/higan/processor/m68k/m68k.cpp @@ -14,11 +14,6 @@ enum : bool { Reverse = 1 }; #include "instruction.cpp" auto M68K::power() -> void { -} - -auto M68K::reset() -> void { - instructionsExecuted = 0; - for(auto& dr : r.d) dr = 0; for(auto& ar : r.a) ar = 0; r.sp = 0; diff --git a/higan/processor/m68k/m68k.hpp b/higan/processor/m68k/m68k.hpp index 8d0843ba..ac8606ad 100644 --- a/higan/processor/m68k/m68k.hpp +++ b/higan/processor/m68k/m68k.hpp @@ -58,7 +58,6 @@ struct M68K { M68K(); auto power() -> void; - auto reset() -> void; auto supervisor() -> bool; auto exception(uint exception, uint vector, uint priority = 7) -> void; @@ -273,7 +272,6 @@ struct M68K { } r; uint16 opcode = 0; - uint instructionsExecuted = 0; function instructionTable[65536]; Bus* bus = nullptr; diff --git a/higan/processor/r6502/r6502.cpp b/higan/processor/r6502/r6502.cpp index 06164256..76144b9b 100644 --- a/higan/processor/r6502/r6502.cpp +++ b/higan/processor/r6502/r6502.cpp @@ -21,14 +21,9 @@ auto R6502::power() -> void { regs.a = 0x00; regs.x = 0x00; regs.y = 0x00; - regs.s = 0x00; + regs.s = 0xff; regs.p = 0x04; -} - -auto R6502::reset() -> void { regs.mdr = 0x00; - regs.s -= 3; - regs.p.i = 1; } auto R6502::interrupt() -> void { diff --git a/higan/processor/r6502/r6502.hpp b/higan/processor/r6502/r6502.hpp index 9dd6206e..46b1516c 100644 --- a/higan/processor/r6502/r6502.hpp +++ b/higan/processor/r6502/r6502.hpp @@ -15,7 +15,6 @@ struct R6502 { auto mdr() const -> uint8; auto power() -> void; - auto reset() -> void; auto interrupt() -> void; auto instruction() -> void; diff --git a/higan/sfc/coprocessor/armdsp/armdsp.cpp b/higan/sfc/coprocessor/armdsp/armdsp.cpp index cfaa17d0..a55f4475 100644 --- a/higan/sfc/coprocessor/armdsp/armdsp.cpp +++ b/higan/sfc/coprocessor/armdsp/armdsp.cpp @@ -94,7 +94,7 @@ auto ArmDSP::write(uint24 addr, uint8 data) -> void { if(addr == 0x3804) { data &= 1; - if(!bridge.reset && data) resetARM(); + if(!bridge.reset && data) reset(); bridge.reset = data; } } @@ -110,14 +110,11 @@ auto ArmDSP::unload() -> void { auto ArmDSP::power() -> void { for(auto n : range(16 * 1024)) programRAM[n] = random(0x00); + bridge.reset = false; + reset(); } auto ArmDSP::reset() -> void { - bridge.reset = false; - resetARM(); -} - -auto ArmDSP::resetARM() -> void { create(ArmDSP::Enter, 21'477'272); ARM::power(); diff --git a/higan/sfc/coprocessor/armdsp/armdsp.hpp b/higan/sfc/coprocessor/armdsp/armdsp.hpp index 68d71bbb..8786caed 100644 --- a/higan/sfc/coprocessor/armdsp/armdsp.hpp +++ b/higan/sfc/coprocessor/armdsp/armdsp.hpp @@ -22,8 +22,7 @@ struct ArmDSP : Processor::ARM, Thread { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; - auto resetARM() -> void; + auto reset() -> void; //soft reset auto firmware() const -> nall::vector; auto serialize(serializer&) -> void; diff --git a/higan/sfc/coprocessor/epsonrtc/epsonrtc.cpp b/higan/sfc/coprocessor/epsonrtc/epsonrtc.cpp index f9638df7..c11b8d83 100644 --- a/higan/sfc/coprocessor/epsonrtc/epsonrtc.cpp +++ b/higan/sfc/coprocessor/epsonrtc/epsonrtc.cpp @@ -78,9 +78,6 @@ auto EpsonRTC::unload() -> void { } auto EpsonRTC::power() -> void { -} - -auto EpsonRTC::reset() -> void { create(EpsonRTC::Enter, 32'768 * 64); clocks = 0; diff --git a/higan/sfc/coprocessor/epsonrtc/epsonrtc.hpp b/higan/sfc/coprocessor/epsonrtc/epsonrtc.hpp index 4a40313f..66e0dd0a 100644 --- a/higan/sfc/coprocessor/epsonrtc/epsonrtc.hpp +++ b/higan/sfc/coprocessor/epsonrtc/epsonrtc.hpp @@ -8,7 +8,6 @@ struct EpsonRTC : Thread { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto sync() -> void; auto read(uint24 addr, uint8 data) -> uint8; diff --git a/higan/sfc/coprocessor/event/event.cpp b/higan/sfc/coprocessor/event/event.cpp index 31e02bc6..15cd3a71 100644 --- a/higan/sfc/coprocessor/event/event.cpp +++ b/higan/sfc/coprocessor/event/event.cpp @@ -43,9 +43,6 @@ auto Event::unload() -> void { } auto Event::power() -> void { -} - -auto Event::reset() -> void { create(Event::Enter, 1); for(auto n : range(ram.size())) ram.write(n, 0x00); diff --git a/higan/sfc/coprocessor/event/event.hpp b/higan/sfc/coprocessor/event/event.hpp index 8bab195f..90301a61 100644 --- a/higan/sfc/coprocessor/event/event.hpp +++ b/higan/sfc/coprocessor/event/event.hpp @@ -9,7 +9,6 @@ struct Event : Thread { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto mcuRead(uint24 addr, uint8) -> uint8; auto mcuWrite(uint24 addr, uint8) -> void; diff --git a/higan/sfc/coprocessor/hitachidsp/hitachidsp.cpp b/higan/sfc/coprocessor/hitachidsp/hitachidsp.cpp index 2aad543d..96fd6c73 100644 --- a/higan/sfc/coprocessor/hitachidsp/hitachidsp.cpp +++ b/higan/sfc/coprocessor/hitachidsp/hitachidsp.cpp @@ -37,6 +37,9 @@ auto HitachiDSP::unload() -> void { } auto HitachiDSP::power() -> void { + HG51B::power(); + create(HitachiDSP::Enter, Frequency); + mmio.dma = false; mmio.dmaSource = 0x000000; @@ -52,9 +55,4 @@ auto HitachiDSP::power() -> void { mmio.r1f52 = 0x01; } -auto HitachiDSP::reset() -> void { - create(HitachiDSP::Enter, Frequency); - HG51B::power(); -} - } diff --git a/higan/sfc/coprocessor/hitachidsp/hitachidsp.hpp b/higan/sfc/coprocessor/hitachidsp/hitachidsp.hpp index 586652f8..cee30bbe 100644 --- a/higan/sfc/coprocessor/hitachidsp/hitachidsp.hpp +++ b/higan/sfc/coprocessor/hitachidsp/hitachidsp.hpp @@ -9,7 +9,6 @@ struct HitachiDSP : Processor::HG51B, Thread { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; //HG51B read/write auto read(uint24 addr) -> uint8 override; diff --git a/higan/sfc/coprocessor/icd2/icd2.cpp b/higan/sfc/coprocessor/icd2/icd2.cpp index 37308a74..5f736b19 100644 --- a/higan/sfc/coprocessor/icd2/icd2.cpp +++ b/higan/sfc/coprocessor/icd2/icd2.cpp @@ -49,12 +49,9 @@ auto ICD2::unload() -> void { } auto ICD2::power() -> void { -} - -auto ICD2::reset(bool soft) -> void { auto frequency = system.colorburst() * 6.0; create(ICD2::Enter, frequency / 5); - if(!soft) stream = Emulator::audio.createStream(2, frequency / 10); + stream = Emulator::audio.createStream(2, frequency / 10); r6003 = 0x00; r6004 = 0xff; @@ -80,6 +77,10 @@ auto ICD2::reset(bool soft) -> void { GameBoy::system.power(); } +auto ICD2::reset() -> void { + //todo: same as power() but without re-creating the audio stream +} + #endif } diff --git a/higan/sfc/coprocessor/icd2/icd2.hpp b/higan/sfc/coprocessor/icd2/icd2.hpp index d80e5bbb..3026d86d 100644 --- a/higan/sfc/coprocessor/icd2/icd2.hpp +++ b/higan/sfc/coprocessor/icd2/icd2.hpp @@ -10,7 +10,7 @@ struct ICD2 : Emulator::Interface::Bind, GameBoy::Interface::Hook, Thread { auto load() -> bool; auto unload() -> void; auto power() -> void; - auto reset(bool soft = false) -> void; + auto reset() -> void; //software reset //interface.cpp auto lcdScanline() -> void override; diff --git a/higan/sfc/coprocessor/mcc/mcc.cpp b/higan/sfc/coprocessor/mcc/mcc.cpp index 7daa64be..13a2fa16 100644 --- a/higan/sfc/coprocessor/mcc/mcc.cpp +++ b/higan/sfc/coprocessor/mcc/mcc.cpp @@ -17,9 +17,6 @@ auto MCC::unload() -> void { } auto MCC::power() -> void { -} - -auto MCC::reset() -> void { for(auto n : range(16)) r[n] = 0x00; r[0x07] = 0x80; r[0x08] = 0x80; diff --git a/higan/sfc/coprocessor/mcc/mcc.hpp b/higan/sfc/coprocessor/mcc/mcc.hpp index 0558b3cb..d372cf64 100644 --- a/higan/sfc/coprocessor/mcc/mcc.hpp +++ b/higan/sfc/coprocessor/mcc/mcc.hpp @@ -8,7 +8,6 @@ struct MCC { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto memoryAccess(bool write, Memory& memory, uint24 addr, uint8 data) -> uint8; auto mcuAccess(bool write, uint24 addr, uint8 data) -> uint8; diff --git a/higan/sfc/coprocessor/msu1/msu1.cpp b/higan/sfc/coprocessor/msu1/msu1.cpp index e432bc61..261edfcf 100644 --- a/higan/sfc/coprocessor/msu1/msu1.cpp +++ b/higan/sfc/coprocessor/msu1/msu1.cpp @@ -51,9 +51,6 @@ auto MSU1::unload() -> void { } auto MSU1::power() -> void { -} - -auto MSU1::reset() -> void { create(MSU1::Enter, 44100); stream = Emulator::audio.createStream(2, 44100.0); diff --git a/higan/sfc/coprocessor/msu1/msu1.hpp b/higan/sfc/coprocessor/msu1/msu1.hpp index 22a2f650..5e9edd5c 100644 --- a/higan/sfc/coprocessor/msu1/msu1.hpp +++ b/higan/sfc/coprocessor/msu1/msu1.hpp @@ -7,7 +7,6 @@ struct MSU1 : Thread { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto dataOpen() -> void; auto audioOpen() -> void; diff --git a/higan/sfc/coprocessor/necdsp/necdsp.cpp b/higan/sfc/coprocessor/necdsp/necdsp.cpp index 6e00fb3a..32857ad4 100644 --- a/higan/sfc/coprocessor/necdsp/necdsp.cpp +++ b/higan/sfc/coprocessor/necdsp/necdsp.cpp @@ -53,11 +53,8 @@ auto NECDSP::unload() -> void { } auto NECDSP::power() -> void { -} - -auto NECDSP::reset() -> void { - create(NECDSP::Enter, Frequency); uPD96050::power(); + create(NECDSP::Enter, Frequency); } } diff --git a/higan/sfc/coprocessor/necdsp/necdsp.hpp b/higan/sfc/coprocessor/necdsp/necdsp.hpp index 9967b21d..47010eea 100644 --- a/higan/sfc/coprocessor/necdsp/necdsp.hpp +++ b/higan/sfc/coprocessor/necdsp/necdsp.hpp @@ -12,7 +12,6 @@ struct NECDSP : Processor::uPD96050, Thread { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto firmware() const -> vector; auto serialize(serializer&) -> void; diff --git a/higan/sfc/coprocessor/nss/nss.cpp b/higan/sfc/coprocessor/nss/nss.cpp index 3274215e..5938631e 100644 --- a/higan/sfc/coprocessor/nss/nss.cpp +++ b/higan/sfc/coprocessor/nss/nss.cpp @@ -16,9 +16,6 @@ auto NSS::unload() -> void { auto NSS::power() -> void { } -auto NSS::reset() -> void { -} - auto NSS::setDip(uint16 dip) -> void { this->dip = dip; } diff --git a/higan/sfc/coprocessor/nss/nss.hpp b/higan/sfc/coprocessor/nss/nss.hpp index cbdb0cd1..bf4ab69e 100644 --- a/higan/sfc/coprocessor/nss/nss.hpp +++ b/higan/sfc/coprocessor/nss/nss.hpp @@ -3,7 +3,6 @@ struct NSS { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto setDip(uint16 dip) -> void; auto read(uint24 addr, uint8 data) -> uint8; diff --git a/higan/sfc/coprocessor/obc1/obc1.cpp b/higan/sfc/coprocessor/obc1/obc1.cpp index 4d0c02c3..c6a33b8b 100644 --- a/higan/sfc/coprocessor/obc1/obc1.cpp +++ b/higan/sfc/coprocessor/obc1/obc1.cpp @@ -16,9 +16,6 @@ auto OBC1::unload() -> void { } auto OBC1::power() -> void { -} - -auto OBC1::reset() -> void { status.baseptr = (ramRead(0x1ff5) & 1) ? 0x1800 : 0x1c00; status.address = (ramRead(0x1ff6) & 0x7f); status.shift = (ramRead(0x1ff6) & 3) << 1; diff --git a/higan/sfc/coprocessor/obc1/obc1.hpp b/higan/sfc/coprocessor/obc1/obc1.hpp index 9ada171b..0ca67a12 100644 --- a/higan/sfc/coprocessor/obc1/obc1.hpp +++ b/higan/sfc/coprocessor/obc1/obc1.hpp @@ -3,7 +3,6 @@ struct OBC1 { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto read(uint24 addr, uint8 data) -> uint8; auto write(uint24 addr, uint8 data) -> void; diff --git a/higan/sfc/coprocessor/sa1/sa1.cpp b/higan/sfc/coprocessor/sa1/sa1.cpp index 3f0c0d79..0593862f 100644 --- a/higan/sfc/coprocessor/sa1/sa1.cpp +++ b/higan/sfc/coprocessor/sa1/sa1.cpp @@ -124,13 +124,6 @@ auto SA1::unload() -> void { } auto SA1::power() -> void { - r.a = 0x0000; - r.x = 0x0000; - r.y = 0x0000; - r.s = 0x01ff; -} - -auto SA1::reset() -> void { create(SA1::Enter, system.colorburst() * 6.0); cpubwram.dma = false; @@ -139,9 +132,10 @@ auto SA1::reset() -> void { } r.pc.d = 0x000000; - r.x.h = 0x00; - r.y.h = 0x00; - r.s.h = 0x01; + r.a = 0x0000; + r.x = 0x0000; + r.y = 0x0000; + r.s = 0x01ff; r.d = 0x0000; r.db = 0x00; r.p = 0x34; diff --git a/higan/sfc/coprocessor/sa1/sa1.hpp b/higan/sfc/coprocessor/sa1/sa1.hpp index 80543e8a..a056b9be 100644 --- a/higan/sfc/coprocessor/sa1/sa1.hpp +++ b/higan/sfc/coprocessor/sa1/sa1.hpp @@ -13,7 +13,6 @@ struct SA1 : Processor::R65816, Thread { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; //bus.cpp struct CPUIRAM : Memory { diff --git a/higan/sfc/coprocessor/sdd1/sdd1.cpp b/higan/sfc/coprocessor/sdd1/sdd1.cpp index 02d83e7d..96813520 100644 --- a/higan/sfc/coprocessor/sdd1/sdd1.cpp +++ b/higan/sfc/coprocessor/sdd1/sdd1.cpp @@ -19,9 +19,6 @@ auto SDD1::unload() -> void { } auto SDD1::power() -> void { -} - -auto SDD1::reset() -> void { //hook S-CPU DMA MMIO registers to gather information for struct dma[]; //buffer address and transfer size information for use in SDD1::mcu_read() bus.map({&SDD1::dmaRead, &sdd1}, {&SDD1::dmaWrite, &sdd1}, "00-3f,80-bf:4300-437f"); diff --git a/higan/sfc/coprocessor/sdd1/sdd1.hpp b/higan/sfc/coprocessor/sdd1/sdd1.hpp index 6a578ce9..b5d9285c 100644 --- a/higan/sfc/coprocessor/sdd1/sdd1.hpp +++ b/higan/sfc/coprocessor/sdd1/sdd1.hpp @@ -3,7 +3,6 @@ struct SDD1 { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto read(uint24 addr, uint8 data) -> uint8; auto write(uint24 addr, uint8 data) -> void; diff --git a/higan/sfc/coprocessor/sharprtc/sharprtc.cpp b/higan/sfc/coprocessor/sharprtc/sharprtc.cpp index e20b931f..46b7bd4d 100644 --- a/higan/sfc/coprocessor/sharprtc/sharprtc.cpp +++ b/higan/sfc/coprocessor/sharprtc/sharprtc.cpp @@ -37,9 +37,6 @@ auto SharpRTC::unload() -> void { } auto SharpRTC::power() -> void { -} - -auto SharpRTC::reset() -> void { create(SharpRTC::Enter, 1); state = State::Read; diff --git a/higan/sfc/coprocessor/sharprtc/sharprtc.hpp b/higan/sfc/coprocessor/sharprtc/sharprtc.hpp index 54d45703..850e379b 100644 --- a/higan/sfc/coprocessor/sharprtc/sharprtc.hpp +++ b/higan/sfc/coprocessor/sharprtc/sharprtc.hpp @@ -6,7 +6,6 @@ struct SharpRTC : Thread { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto sync() -> void; auto read(uint24 addr, uint8 data) -> uint8; diff --git a/higan/sfc/coprocessor/spc7110/spc7110.cpp b/higan/sfc/coprocessor/spc7110/spc7110.cpp index b98a0c4d..afb34774 100644 --- a/higan/sfc/coprocessor/spc7110/spc7110.cpp +++ b/higan/sfc/coprocessor/spc7110/spc7110.cpp @@ -45,9 +45,6 @@ auto SPC7110::unload() -> void { } auto SPC7110::power() -> void { -} - -auto SPC7110::reset() -> void { create(SPC7110::Enter, 21'477'272); r4801 = 0x00; diff --git a/higan/sfc/coprocessor/spc7110/spc7110.hpp b/higan/sfc/coprocessor/spc7110/spc7110.hpp index cea52a60..ea8bc713 100644 --- a/higan/sfc/coprocessor/spc7110/spc7110.hpp +++ b/higan/sfc/coprocessor/spc7110/spc7110.hpp @@ -10,7 +10,6 @@ struct SPC7110 : Thread { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto addClocks(uint clocks) -> void; diff --git a/higan/sfc/coprocessor/superfx/superfx.cpp b/higan/sfc/coprocessor/superfx/superfx.cpp index ab961162..c523149b 100644 --- a/higan/sfc/coprocessor/superfx/superfx.cpp +++ b/higan/sfc/coprocessor/superfx/superfx.cpp @@ -44,10 +44,6 @@ auto SuperFX::unload() -> void { auto SuperFX::power() -> void { GSU::power(); -} - -auto SuperFX::reset() -> void { - GSU::reset(); create(SuperFX::Enter, system.colorburst() * 6.0); romMask = rom.size() - 1; diff --git a/higan/sfc/coprocessor/superfx/superfx.hpp b/higan/sfc/coprocessor/superfx/superfx.hpp index 2d9f7d9f..95a57664 100644 --- a/higan/sfc/coprocessor/superfx/superfx.hpp +++ b/higan/sfc/coprocessor/superfx/superfx.hpp @@ -9,7 +9,6 @@ struct SuperFX : Processor::GSU, Thread { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; //bus.cpp struct CPUROM : Memory { diff --git a/higan/sfc/cpu/cpu.cpp b/higan/sfc/cpu/cpu.cpp index 4dbc9aff..0aef901b 100644 --- a/higan/sfc/cpu/cpu.cpp +++ b/higan/sfc/cpu/cpu.cpp @@ -56,41 +56,6 @@ auto CPU::load(Markup::Node node) -> bool { } auto CPU::power() -> void { - for(auto& byte : wram) byte = random(0x55); - - //CPU - r.a = 0x0000; - r.x = 0x0000; - r.y = 0x0000; - r.s = 0x01ff; - - //DMA - for(auto& channel : this->channel) { - channel.direction = 1; - channel.indirect = true; - channel.unused = true; - channel.reverseTransfer = true; - channel.fixedTransfer = true; - channel.transferMode = 7; - - channel.targetAddress = 0xff; - - channel.sourceAddress = 0xffff; - channel.sourceBank = 0xff; - - channel.transferSize = 0xffff; - channel.indirectBank = 0xff; - - channel.hdmaAddress = 0xffff; - channel.lineCounter = 0xff; - channel.unknown = 0xff; - } - - status.powerPending = true; - status.interruptPending = true; -} - -auto CPU::reset() -> void { create(Enter, system.colorburst() * 6.0); coprocessors.reset(); PPUcounter::reset(); @@ -115,11 +80,14 @@ auto CPU::reset() -> void { bus.map(reader, writer, "00-3f,80-bf:0000-1fff", 0x2000); bus.map(reader, writer, "7e-7f:0000-ffff", 0x20000); + for(auto& byte : wram) byte = random(0x55); + //CPU r.pc = 0x000000; - r.x.h = 0x00; - r.y.h = 0x00; - r.s.h = 0x01; + r.a = 0x0000; + r.x = 0x0000; + r.y = 0x0000; + r.s = 0x01ff; r.d = 0x0000; r.db = 0x00; r.p = 0x34; @@ -128,6 +96,34 @@ auto CPU::reset() -> void { r.wai = false; r.vector = 0xfffc; //reset vector address + //DMA + for(auto& channel : this->channel) { + channel.dmaEnabled = false; + channel.hdmaEnabled = false; + + channel.direction = 1; + channel.indirect = true; + channel.unused = true; + channel.reverseTransfer = true; + channel.fixedTransfer = true; + channel.transferMode = 7; + + channel.targetAddress = 0xff; + + channel.sourceAddress = 0xffff; + channel.sourceBank = 0xff; + + channel.transferSize = 0xffff; + channel.indirectBank = 0xff; + + channel.hdmaAddress = 0xffff; + channel.lineCounter = 0xff; + channel.unknown = 0xff; + + channel.hdmaCompleted = false; + channel.hdmaDoTransfer = false; + } + //$2140-217f for(auto& port : io.port) port = 0x00; @@ -176,15 +172,7 @@ auto CPU::reset() -> void { alu.divctr = 0; alu.shift = 0; - //DMA - for(auto& channel : this->channel) { - channel.dmaEnabled = false; - channel.hdmaEnabled = false; - - channel.hdmaCompleted = false; - channel.hdmaDoTransfer = false; - } - + //Pipe pipe.valid = false; pipe.addr = 0; pipe.data = 0; @@ -215,7 +203,8 @@ auto CPU::reset() -> void { status.irqPending = false; status.irqHold = false; - status.resetPending = !status.powerPending; + status.powerPending = true; + status.resetPending = false; status.interruptPending = true; status.dmaActive = false; diff --git a/higan/sfc/cpu/cpu.hpp b/higan/sfc/cpu/cpu.hpp index 55ec63cb..f252104c 100644 --- a/higan/sfc/cpu/cpu.hpp +++ b/higan/sfc/cpu/cpu.hpp @@ -12,7 +12,6 @@ struct CPU : Processor::R65816, Thread, PPUcounter { auto main() -> void; auto load(Markup::Node) -> bool; auto power() -> void; - auto reset() -> void; //dma.cpp auto dmaStep(uint clocks) -> void; diff --git a/higan/sfc/dsp/dsp.cpp b/higan/sfc/dsp/dsp.cpp index 535e3a21..3a4d2d5e 100644 --- a/higan/sfc/dsp/dsp.cpp +++ b/higan/sfc/dsp/dsp.cpp @@ -229,7 +229,15 @@ auto DSP::load(Markup::Node node) -> bool { } auto DSP::power() -> void { + create(Enter, 32040.0 * 768.0); + stream = Emulator::audio.createStream(2, 32040.0); + memory::fill(&state, sizeof(State)); + state.noise = 0x4000; + state.echoHistoryOffset = 0; + state.everyOtherSample = 1; + state.echoOffset = 0; + state.counter = 0; for(auto n : range(8)) { memory::fill(&voice[n], sizeof(Voice)); @@ -237,18 +245,8 @@ auto DSP::power() -> void { voice[n].vbit = 1 << n; voice[n].vidx = n * 0x10; } -} - -auto DSP::reset() -> void { - create(Enter, 32040.0 * 768.0); - stream = Emulator::audio.createStream(2, 32040.0); REG(FLG) = 0xe0; - state.noise = 0x4000; - state.echoHistoryOffset = 0; - state.everyOtherSample = 1; - state.echoOffset = 0; - state.counter = 0; } #undef REG diff --git a/higan/sfc/dsp/dsp.hpp b/higan/sfc/dsp/dsp.hpp index 7cee1d31..2b561a44 100644 --- a/higan/sfc/dsp/dsp.hpp +++ b/higan/sfc/dsp/dsp.hpp @@ -14,7 +14,6 @@ struct DSP : Thread { auto main() -> void; auto load(Markup::Node) -> bool; auto power() -> void; - auto reset() -> void; //serialization.cpp auto serialize(serializer&) -> void; diff --git a/higan/sfc/interface/interface.cpp b/higan/sfc/interface/interface.cpp index 58c0e25d..f1edde83 100644 --- a/higan/sfc/interface/interface.cpp +++ b/higan/sfc/interface/interface.cpp @@ -10,7 +10,6 @@ Interface::Interface() { information.manufacturer = "Nintendo"; information.name = "Super Famicom"; information.overscan = true; - information.resettable = true; information.capability.states = true; information.capability.cheats = true; @@ -207,10 +206,6 @@ auto Interface::power() -> void { system.power(); } -auto Interface::reset() -> void { - system.reset(); -} - auto Interface::run() -> void { system.run(); } diff --git a/higan/sfc/interface/interface.hpp b/higan/sfc/interface/interface.hpp index d0176ed3..f7250b23 100644 --- a/higan/sfc/interface/interface.hpp +++ b/higan/sfc/interface/interface.hpp @@ -54,7 +54,6 @@ struct Interface : Emulator::Interface { auto connect(uint port, uint device) -> void override; auto power() -> void override; - auto reset() -> void override; auto run() -> void override; auto rtc() -> bool override; diff --git a/higan/sfc/ppu/background/background.cpp b/higan/sfc/ppu/background/background.cpp index 34407330..be155942 100644 --- a/higan/sfc/ppu/background/background.cpp +++ b/higan/sfc/ppu/background/background.cpp @@ -206,7 +206,7 @@ auto PPU::Background::getTileColor() -> uint { return color; } -auto PPU::Background::reset() -> void { +auto PPU::Background::power() -> void { io.tiledataAddress = (random(0x0000) & 0x0f) << 12; io.screenAddress = (random(0x0000) & 0xfc) << 8; io.screenSize = random(0); diff --git a/higan/sfc/ppu/background/background.hpp b/higan/sfc/ppu/background/background.hpp index 5879d2fb..b6ddc33e 100644 --- a/higan/sfc/ppu/background/background.hpp +++ b/higan/sfc/ppu/background/background.hpp @@ -8,7 +8,7 @@ struct Background { auto scanline() -> void; auto begin() -> void; auto run(bool screen) -> void; - auto reset() -> void; + auto power() -> void; auto getTile() -> void; auto getTileColor() -> uint; diff --git a/higan/sfc/ppu/object/object.cpp b/higan/sfc/ppu/object/object.cpp index 39ae9b58..9777bd17 100644 --- a/higan/sfc/ppu/object/object.cpp +++ b/higan/sfc/ppu/object/object.cpp @@ -154,7 +154,7 @@ auto PPU::Object::tilefetch() -> void { io.rangeOver |= (t.itemCount > 32); } -auto PPU::Object::reset() -> void { +auto PPU::Object::power() -> void { for(auto& object : oam.object) { object.x = 0; object.y = 0; diff --git a/higan/sfc/ppu/object/object.hpp b/higan/sfc/ppu/object/object.hpp index 66242a6f..f667f744 100644 --- a/higan/sfc/ppu/object/object.hpp +++ b/higan/sfc/ppu/object/object.hpp @@ -25,7 +25,7 @@ struct Object { auto scanline() -> void; auto run() -> void; auto tilefetch() -> void; - auto reset() -> void; + auto power() -> void; auto onScanline(PPU::OAM::Object&) -> bool; diff --git a/higan/sfc/ppu/ppu.cpp b/higan/sfc/ppu/ppu.cpp index faa45714..d0aa57a7 100644 --- a/higan/sfc/ppu/ppu.cpp +++ b/higan/sfc/ppu/ppu.cpp @@ -87,10 +87,6 @@ auto PPU::load(Markup::Node node) -> bool { } auto PPU::power() -> void { - for(auto& n : vram.data) n = random(0x0000); -} - -auto PPU::reset() -> void { create(Enter, system.colorburst() * 6.0); PPUcounter::reset(); memory::fill(output, 512 * 480 * sizeof(uint32)); @@ -99,6 +95,8 @@ auto PPU::reset() -> void { function void> writer{&PPU::writeIO, this}; bus.map(reader, writer, "00-3f,80-bf:2100-213f"); + for(auto& n : vram.data) n = random(0x0000); + ppu1.mdr = random(0xff); ppu2.mdr = random(0xff); @@ -182,13 +180,13 @@ auto PPU::reset() -> void { //$213d OPVCT io.vcounter = 0; - bg1.reset(); - bg2.reset(); - bg3.reset(); - bg4.reset(); - obj.reset(); - window.reset(); - screen.reset(); + bg1.power(); + bg2.power(); + bg3.power(); + bg4.power(); + obj.power(); + window.power(); + screen.power(); frame(); } diff --git a/higan/sfc/ppu/ppu.hpp b/higan/sfc/ppu/ppu.hpp index 7be05c9c..1bd3ab70 100644 --- a/higan/sfc/ppu/ppu.hpp +++ b/higan/sfc/ppu/ppu.hpp @@ -12,7 +12,6 @@ struct PPU : Thread, PPUcounter { auto main() -> void; auto load(Markup::Node) -> bool; auto power() -> void; - auto reset() -> void; auto serialize(serializer&) -> void; diff --git a/higan/sfc/ppu/screen/screen.cpp b/higan/sfc/ppu/screen/screen.cpp index c04a6da6..bc2cac01 100644 --- a/higan/sfc/ppu/screen/screen.cpp +++ b/higan/sfc/ppu/screen/screen.cpp @@ -160,7 +160,7 @@ auto PPU::Screen::fixedColor() const -> uint15 { return io.colorBlue << 10 | io.colorGreen << 5 | io.colorRed << 0; } -auto PPU::Screen::reset() -> void { +auto PPU::Screen::power() -> void { for(auto& n : cgram) n = random(0x0000); io.blendMode = random(false); diff --git a/higan/sfc/ppu/screen/screen.hpp b/higan/sfc/ppu/screen/screen.hpp index d1061710..5a886477 100644 --- a/higan/sfc/ppu/screen/screen.hpp +++ b/higan/sfc/ppu/screen/screen.hpp @@ -1,7 +1,7 @@ struct Screen { auto scanline() -> void; alwaysinline auto run() -> void; - auto reset() -> void; + auto power() -> void; auto below(bool hires) -> uint16; auto above() -> uint16; diff --git a/higan/sfc/ppu/window/window.cpp b/higan/sfc/ppu/window/window.cpp index 477f85f2..8fd2e442 100644 --- a/higan/sfc/ppu/window/window.cpp +++ b/higan/sfc/ppu/window/window.cpp @@ -46,7 +46,7 @@ auto PPU::Window::test(bool oneEnable, bool one, bool twoEnable, bool two, uint return (one ^ two) == 3 - mask; } -auto PPU::Window::reset() -> void { +auto PPU::Window::power() -> void { io.bg1.oneEnable = random(false); io.bg1.oneInvert = random(false); io.bg1.twoEnable = random(false); diff --git a/higan/sfc/ppu/window/window.hpp b/higan/sfc/ppu/window/window.hpp index d23b6897..ff3d8453 100644 --- a/higan/sfc/ppu/window/window.hpp +++ b/higan/sfc/ppu/window/window.hpp @@ -2,7 +2,7 @@ struct Window { auto scanline() -> void; auto run() -> void; auto test(bool oneEnable, bool one, bool twoEnable, bool two, uint mask) -> bool; - auto reset() -> void; + auto power() -> void; auto serialize(serializer&) -> void; diff --git a/higan/sfc/slot/bsmemory/bsmemory.cpp b/higan/sfc/slot/bsmemory/bsmemory.cpp index 0681bb75..3906e448 100644 --- a/higan/sfc/slot/bsmemory/bsmemory.cpp +++ b/higan/sfc/slot/bsmemory/bsmemory.cpp @@ -18,9 +18,6 @@ auto BSMemory::unload() -> void { } auto BSMemory::power() -> void { -} - -auto BSMemory::reset() -> void { regs.command = 0; regs.writeOld = 0x00; regs.writeNew = 0x00; diff --git a/higan/sfc/slot/bsmemory/bsmemory.hpp b/higan/sfc/slot/bsmemory/bsmemory.hpp index 6c3abd2a..0be530c4 100644 --- a/higan/sfc/slot/bsmemory/bsmemory.hpp +++ b/higan/sfc/slot/bsmemory/bsmemory.hpp @@ -3,7 +3,6 @@ struct BSMemory : Memory { auto load() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; auto size() const -> uint; auto read(uint24 addr, uint8) -> uint8; diff --git a/higan/sfc/smp/smp.cpp b/higan/sfc/smp/smp.cpp index 90cb1180..ccdc8478 100644 --- a/higan/sfc/smp/smp.cpp +++ b/higan/sfc/smp/smp.cpp @@ -27,13 +27,6 @@ auto SMP::load(Markup::Node node) -> bool { } auto SMP::power() -> void { - //targets not initialized/changed upon reset - timer0.target = 0; - timer1.target = 0; - timer2.target = 0; -} - -auto SMP::reset() -> void { create(Enter, 32040.0 * 768.0); regs.pc.l = iplrom[62]; @@ -95,6 +88,10 @@ auto SMP::reset() -> void { timer0.enable = false; timer1.enable = false; timer2.enable = false; + + timer0.target = 0; + timer1.target = 0; + timer2.target = 0; } } diff --git a/higan/sfc/smp/smp.hpp b/higan/sfc/smp/smp.hpp index ad4d88b0..c6b70dd5 100644 --- a/higan/sfc/smp/smp.hpp +++ b/higan/sfc/smp/smp.hpp @@ -7,7 +7,6 @@ struct SMP : Processor::SPC700, Thread { auto main() -> void; auto load(Markup::Node) -> bool; auto power() -> void; - auto reset() -> void; auto serialize(serializer&) -> void; diff --git a/higan/sfc/system/system.cpp b/higan/sfc/system/system.cpp index c90a73b3..f90a6d4a 100644 --- a/higan/sfc/system/system.cpp +++ b/higan/sfc/system/system.cpp @@ -128,8 +128,17 @@ auto System::unload() -> void { } auto System::power() -> void { + Emulator::video.reset(); + Emulator::video.setInterface(interface); + configureVideoPalette(); + configureVideoEffects(); + + Emulator::audio.reset(); + Emulator::audio.setInterface(interface); + random.seed((uint)time(0)); + scheduler.reset(); cpu.power(); smp.power(); dsp.power(); @@ -153,42 +162,6 @@ auto System::power() -> void { if(cartridge.has.BSMemorySlot) bsmemory.power(); - reset(); -} - -auto System::reset() -> void { - Emulator::video.reset(); - Emulator::video.setInterface(interface); - configureVideoPalette(); - configureVideoEffects(); - - Emulator::audio.reset(); - Emulator::audio.setInterface(interface); - - scheduler.reset(); - cpu.reset(); - smp.reset(); - dsp.reset(); - ppu.reset(); - - if(cartridge.has.ICD2) icd2.reset(); - if(cartridge.has.MCC) mcc.reset(); - if(cartridge.has.NSSDIP) nss.reset(); - if(cartridge.has.Event) event.reset(); - if(cartridge.has.SA1) sa1.reset(); - if(cartridge.has.SuperFX) superfx.reset(); - if(cartridge.has.ARMDSP) armdsp.reset(); - if(cartridge.has.HitachiDSP) hitachidsp.reset(); - if(cartridge.has.NECDSP) necdsp.reset(); - if(cartridge.has.EpsonRTC) epsonrtc.reset(); - if(cartridge.has.SharpRTC) sharprtc.reset(); - if(cartridge.has.SPC7110) spc7110.reset(); - if(cartridge.has.SDD1) sdd1.reset(); - if(cartridge.has.OBC1) obc1.reset(); - if(cartridge.has.MSU1) msu1.reset(); - - if(cartridge.has.BSMemorySlot) bsmemory.reset(); - if(cartridge.has.ICD2) cpu.coprocessors.append(&icd2); if(cartridge.has.Event) cpu.coprocessors.append(&event); if(cartridge.has.SA1) cpu.coprocessors.append(&sa1); diff --git a/higan/sfc/system/system.hpp b/higan/sfc/system/system.hpp index 4c2f6a8e..bd324df5 100644 --- a/higan/sfc/system/system.hpp +++ b/higan/sfc/system/system.hpp @@ -14,7 +14,6 @@ struct System { auto save() -> void; auto unload() -> void; auto power() -> void; - auto reset() -> void; //video.cpp auto configureVideoPalette() -> void; diff --git a/higan/target-tomoko/program/program.cpp b/higan/target-tomoko/program/program.cpp index bccaac7c..b0d9fb2b 100644 --- a/higan/target-tomoko/program/program.cpp +++ b/higan/target-tomoko/program/program.cpp @@ -23,10 +23,12 @@ Program::Program(string_vector args) { emulators.append(new MasterSystem::MasterSystemInterface); emulators.append(new MegaDrive::Interface); emulators.append(new PCEngine::Interface); - emulators.append(new GameBoy::Interface); + emulators.append(new GameBoy::GameBoyInterface); + emulators.append(new GameBoy::GameBoyColorInterface); emulators.append(new GameBoyAdvance::Interface); emulators.append(new MasterSystem::GameGearInterface); - emulators.append(new WonderSwan::Interface); + emulators.append(new WonderSwan::WonderSwanInterface); + emulators.append(new WonderSwan::WonderSwanColorInterface); new Presentation; presentation->setVisible(); diff --git a/higan/ws/interface/interface.cpp b/higan/ws/interface/interface.cpp index 5c33003e..b19f4a7b 100644 --- a/higan/ws/interface/interface.cpp +++ b/higan/ws/interface/interface.cpp @@ -3,165 +3,7 @@ namespace WonderSwan { Settings settings; - -Interface::Interface() { - information.manufacturer = "Bandai"; - information.name = "WonderSwan"; - information.overscan = false; - information.resettable = false; - - information.capability.states = true; - information.capability.cheats = true; - - media.append({ID::WonderSwan, "WonderSwan", "ws" }); - media.append({ID::WonderSwanColor, "WonderSwan Color", "wsc"}); - - Port hardwareHorizontalPort{ID::Port::HardwareHorizontal, "Hardware - Horizontal"}; - Port hardwareVerticalPort{ID::Port::HardwareVertical, "Hardware - Vertical"}; - - { Device device{ID::Device::Controls, "Controls"}; - device.inputs.append({0, "Y1"}); - device.inputs.append({0, "Y2"}); - device.inputs.append({0, "Y3"}); - device.inputs.append({0, "Y4"}); - device.inputs.append({0, "X1"}); - device.inputs.append({0, "X2"}); - device.inputs.append({0, "X3"}); - device.inputs.append({0, "X4"}); - device.inputs.append({0, "B"}); - device.inputs.append({0, "A"}); - device.inputs.append({0, "Start"}); - device.inputs.append({0, "Rotate"}); - hardwareHorizontalPort.devices.append(device); - hardwareVerticalPort.devices.append(device); - } - - ports.append(move(hardwareHorizontalPort)); - ports.append(move(hardwareVerticalPort)); -} - -auto Interface::manifest() -> string { - return cartridge.information.manifest; -} - -auto Interface::title() -> string { - return cartridge.information.title; -} - -auto Interface::videoSize() -> VideoSize { - return {224, 224}; -} - -auto Interface::videoSize(uint width, uint height, bool arc) -> VideoSize { - uint w = 224; - uint h = 224; - uint m = min(width / w, height / h); - return {w * m, h * m}; -} - -auto Interface::videoFrequency() -> double { - return 3072000.0 / (159.0 * 256.0); //~75.47hz -} - -auto Interface::videoColors() -> uint32 { - return 1 << 12; -} - -auto Interface::videoColor(uint32 color) -> uint64 { - uint b = color.bits(0, 3); - uint g = color.bits(4, 7); - uint r = color.bits(8,11); - - uint64_t R = image::normalize(r, 4, 16); - uint64_t G = image::normalize(g, 4, 16); - uint64_t B = image::normalize(b, 4, 16); - - if(settings.colorEmulation) { - R = (r * 26 + g * 4 + b * 2); - G = ( g * 24 + b * 8); - B = (r * 6 + g * 4 + b * 22); - R = image::normalize(min(480, R), 9, 16); - G = image::normalize(min(480, G), 9, 16); - B = image::normalize(min(480, B), 9, 16); - } - - return R << 32 | G << 16 | B << 0; -} - -auto Interface::audioFrequency() -> double { - return 3072000.0; -} - -auto Interface::loaded() -> bool { - return system.loaded(); -} - -auto Interface::sha256() -> string { - return cartridge.information.sha256; -} - -auto Interface::load(uint id) -> bool { - if(id == ID::WonderSwan) return system.load(this, Model::WonderSwan); - if(id == ID::WonderSwanColor) return system.load(this, Model::WonderSwanColor); - return false; -} - -auto Interface::save() -> void { - system.save(); -} - -auto Interface::unload() -> void { - save(); - system.unload(); -} - -auto Interface::power() -> void { - system.power(); -} - -auto Interface::run() -> void { - system.run(); -} - -auto Interface::serialize() -> serializer { - system.runToSave(); - return system.serialize(); -} - -auto Interface::unserialize(serializer& s) -> bool { - return system.unserialize(s); -} - -auto Interface::cheatSet(const string_vector& list) -> void { - cheat.assign(list); -} - -auto Interface::cap(const string& name) -> bool { - if(name == "Blur Emulation") return true; - if(name == "Color Emulation") return true; - return false; -} - -auto Interface::get(const string& name) -> any { - if(name == "Blur Emulation") return settings.blurEmulation; - if(name == "Color Emulation") return settings.colorEmulation; - return {}; -} - -auto Interface::set(const string& name, const any& value) -> bool { - if(name == "Blur Emulation" && value.is()) { - settings.blurEmulation = value.get(); - system.configureVideoEffects(); - return true; - } - - if(name == "Color Emulation" && value.is()) { - settings.colorEmulation = value.get(); - system.configureVideoPalette(); - return true; - } - - return false; -} +#include "wonderswan.cpp" +#include "wonderswan-color.cpp" } diff --git a/higan/ws/interface/interface.hpp b/higan/ws/interface/interface.hpp index 55683d89..0548a21d 100644 --- a/higan/ws/interface/interface.hpp +++ b/higan/ws/interface/interface.hpp @@ -17,10 +17,45 @@ struct ID { };}; }; -struct Interface : Emulator::Interface { +struct WonderSwanInterface : Emulator::Interface { using Emulator::Interface::load; - Interface(); + WonderSwanInterface(); + + auto manifest() -> string override; + auto title() -> string override; + + auto videoSize() -> VideoSize override; + auto videoSize(uint width, uint height, bool arc) -> VideoSize override; + auto videoFrequency() -> double override; + auto videoColors() -> uint32; + auto videoColor(uint32 color) -> uint64; + + auto audioFrequency() -> double override; + + auto loaded() -> bool override; + auto sha256() -> string override; + auto load(uint id) -> bool override; + auto save() -> void override; + auto unload() -> void override; + + auto power() -> void override; + auto run() -> void override; + + auto serialize() -> serializer override; + auto unserialize(serializer&) -> bool override; + + auto cheatSet(const string_vector&) -> void override; + + auto cap(const string& name) -> bool override; + auto get(const string& name) -> any override; + auto set(const string& name, const any& value) -> bool override; +}; + +struct WonderSwanColorInterface : Emulator::Interface { + using Emulator::Interface::load; + + WonderSwanColorInterface(); auto manifest() -> string override; auto title() -> string override; diff --git a/higan/ws/interface/wonderswan-color.cpp b/higan/ws/interface/wonderswan-color.cpp new file mode 100644 index 00000000..c5291576 --- /dev/null +++ b/higan/ws/interface/wonderswan-color.cpp @@ -0,0 +1,156 @@ +WonderSwanColorInterface::WonderSwanColorInterface() { + information.manufacturer = "Bandai"; + information.name = "WonderSwan Color"; + information.overscan = false; + + information.capability.states = true; + information.capability.cheats = true; + + media.append({ID::WonderSwanColor, "WonderSwan Color", "wsc"}); + + Port hardwareHorizontalPort{ID::Port::HardwareHorizontal, "Hardware - Horizontal"}; + Port hardwareVerticalPort{ID::Port::HardwareVertical, "Hardware - Vertical"}; + + { Device device{ID::Device::Controls, "Controls"}; + device.inputs.append({0, "Y1"}); + device.inputs.append({0, "Y2"}); + device.inputs.append({0, "Y3"}); + device.inputs.append({0, "Y4"}); + device.inputs.append({0, "X1"}); + device.inputs.append({0, "X2"}); + device.inputs.append({0, "X3"}); + device.inputs.append({0, "X4"}); + device.inputs.append({0, "B"}); + device.inputs.append({0, "A"}); + device.inputs.append({0, "Start"}); + device.inputs.append({0, "Rotate"}); + hardwareHorizontalPort.devices.append(device); + hardwareVerticalPort.devices.append(device); + } + + ports.append(move(hardwareHorizontalPort)); + ports.append(move(hardwareVerticalPort)); +} + +auto WonderSwanColorInterface::manifest() -> string { + return cartridge.information.manifest; +} + +auto WonderSwanColorInterface::title() -> string { + return cartridge.information.title; +} + +auto WonderSwanColorInterface::videoSize() -> VideoSize { + return {224, 224}; +} + +auto WonderSwanColorInterface::videoSize(uint width, uint height, bool arc) -> VideoSize { + uint w = 224; + uint h = 224; + uint m = min(width / w, height / h); + return {w * m, h * m}; +} + +auto WonderSwanColorInterface::videoFrequency() -> double { + return 3072000.0 / (159.0 * 256.0); //~75.47hz +} + +auto WonderSwanColorInterface::videoColors() -> uint32 { + return 1 << 12; +} + +auto WonderSwanColorInterface::videoColor(uint32 color) -> uint64 { + uint b = color.bits(0, 3); + uint g = color.bits(4, 7); + uint r = color.bits(8,11); + + uint64_t R = image::normalize(r, 4, 16); + uint64_t G = image::normalize(g, 4, 16); + uint64_t B = image::normalize(b, 4, 16); + + if(settings.colorEmulation) { + R = (r * 26 + g * 4 + b * 2); + G = ( g * 24 + b * 8); + B = (r * 6 + g * 4 + b * 22); + R = image::normalize(min(480, R), 9, 16); + G = image::normalize(min(480, G), 9, 16); + B = image::normalize(min(480, B), 9, 16); + } + + return R << 32 | G << 16 | B << 0; +} + +auto WonderSwanColorInterface::audioFrequency() -> double { + return 3072000.0; +} + +auto WonderSwanColorInterface::loaded() -> bool { + return system.loaded(); +} + +auto WonderSwanColorInterface::sha256() -> string { + return cartridge.information.sha256; +} + +auto WonderSwanColorInterface::load(uint id) -> bool { + if(id == ID::WonderSwanColor) return system.load(this, Model::WonderSwanColor); + return false; +} + +auto WonderSwanColorInterface::save() -> void { + system.save(); +} + +auto WonderSwanColorInterface::unload() -> void { + save(); + system.unload(); +} + +auto WonderSwanColorInterface::power() -> void { + system.power(); +} + +auto WonderSwanColorInterface::run() -> void { + system.run(); +} + +auto WonderSwanColorInterface::serialize() -> serializer { + system.runToSave(); + return system.serialize(); +} + +auto WonderSwanColorInterface::unserialize(serializer& s) -> bool { + return system.unserialize(s); +} + +auto WonderSwanColorInterface::cheatSet(const string_vector& list) -> void { + cheat.assign(list); +} + +auto WonderSwanColorInterface::cap(const string& name) -> bool { + if(name == "Blur Emulation") return true; + if(name == "Color Emulation") return true; + return false; +} + +auto WonderSwanColorInterface::get(const string& name) -> any { + if(name == "Blur Emulation") return settings.blurEmulation; + if(name == "Color Emulation") return settings.colorEmulation; + return {}; +} + +auto WonderSwanColorInterface::set(const string& name, const any& value) -> bool { + if(name == "Blur Emulation" && value.is()) { + settings.blurEmulation = value.get(); + system.configureVideoEffects(); + return true; + } + + if(name == "Color Emulation" && value.is()) { + settings.colorEmulation = value.get(); + system.configureVideoPalette(); + return true; + } + + return false; +} diff --git a/higan/ws/interface/wonderswan.cpp b/higan/ws/interface/wonderswan.cpp new file mode 100644 index 00000000..e9f78361 --- /dev/null +++ b/higan/ws/interface/wonderswan.cpp @@ -0,0 +1,156 @@ +WonderSwanInterface::WonderSwanInterface() { + information.manufacturer = "Bandai"; + information.name = "WonderSwan"; + information.overscan = false; + + information.capability.states = true; + information.capability.cheats = true; + + media.append({ID::WonderSwan, "WonderSwan", "ws"}); + + Port hardwareHorizontalPort{ID::Port::HardwareHorizontal, "Hardware - Horizontal"}; + Port hardwareVerticalPort{ID::Port::HardwareVertical, "Hardware - Vertical"}; + + { Device device{ID::Device::Controls, "Controls"}; + device.inputs.append({0, "Y1"}); + device.inputs.append({0, "Y2"}); + device.inputs.append({0, "Y3"}); + device.inputs.append({0, "Y4"}); + device.inputs.append({0, "X1"}); + device.inputs.append({0, "X2"}); + device.inputs.append({0, "X3"}); + device.inputs.append({0, "X4"}); + device.inputs.append({0, "B"}); + device.inputs.append({0, "A"}); + device.inputs.append({0, "Start"}); + device.inputs.append({0, "Rotate"}); + hardwareHorizontalPort.devices.append(device); + hardwareVerticalPort.devices.append(device); + } + + ports.append(move(hardwareHorizontalPort)); + ports.append(move(hardwareVerticalPort)); +} + +auto WonderSwanInterface::manifest() -> string { + return cartridge.information.manifest; +} + +auto WonderSwanInterface::title() -> string { + return cartridge.information.title; +} + +auto WonderSwanInterface::videoSize() -> VideoSize { + return {224, 224}; +} + +auto WonderSwanInterface::videoSize(uint width, uint height, bool arc) -> VideoSize { + uint w = 224; + uint h = 224; + uint m = min(width / w, height / h); + return {w * m, h * m}; +} + +auto WonderSwanInterface::videoFrequency() -> double { + return 3072000.0 / (159.0 * 256.0); //~75.47hz +} + +auto WonderSwanInterface::videoColors() -> uint32 { + return 1 << 12; +} + +auto WonderSwanInterface::videoColor(uint32 color) -> uint64 { + uint b = color.bits(0, 3); + uint g = color.bits(4, 7); + uint r = color.bits(8,11); + + uint64_t R = image::normalize(r, 4, 16); + uint64_t G = image::normalize(g, 4, 16); + uint64_t B = image::normalize(b, 4, 16); + + if(settings.colorEmulation) { + R = (r * 26 + g * 4 + b * 2); + G = ( g * 24 + b * 8); + B = (r * 6 + g * 4 + b * 22); + R = image::normalize(min(480, R), 9, 16); + G = image::normalize(min(480, G), 9, 16); + B = image::normalize(min(480, B), 9, 16); + } + + return R << 32 | G << 16 | B << 0; +} + +auto WonderSwanInterface::audioFrequency() -> double { + return 3072000.0; +} + +auto WonderSwanInterface::loaded() -> bool { + return system.loaded(); +} + +auto WonderSwanInterface::sha256() -> string { + return cartridge.information.sha256; +} + +auto WonderSwanInterface::load(uint id) -> bool { + if(id == ID::WonderSwan) return system.load(this, Model::WonderSwan); + return false; +} + +auto WonderSwanInterface::save() -> void { + system.save(); +} + +auto WonderSwanInterface::unload() -> void { + save(); + system.unload(); +} + +auto WonderSwanInterface::power() -> void { + system.power(); +} + +auto WonderSwanInterface::run() -> void { + system.run(); +} + +auto WonderSwanInterface::serialize() -> serializer { + system.runToSave(); + return system.serialize(); +} + +auto WonderSwanInterface::unserialize(serializer& s) -> bool { + return system.unserialize(s); +} + +auto WonderSwanInterface::cheatSet(const string_vector& list) -> void { + cheat.assign(list); +} + +auto WonderSwanInterface::cap(const string& name) -> bool { + if(name == "Blur Emulation") return true; + if(name == "Color Emulation") return true; + return false; +} + +auto WonderSwanInterface::get(const string& name) -> any { + if(name == "Blur Emulation") return settings.blurEmulation; + if(name == "Color Emulation") return settings.colorEmulation; + return {}; +} + +auto WonderSwanInterface::set(const string& name, const any& value) -> bool { + if(name == "Blur Emulation" && value.is()) { + settings.blurEmulation = value.get(); + system.configureVideoEffects(); + return true; + } + + if(name == "Color Emulation" && value.is()) { + settings.colorEmulation = value.get(); + system.configureVideoPalette(); + return true; + } + + return false; +} diff --git a/hiro/cocoa/header.hpp b/hiro/cocoa/header.hpp index 8dd9cb90..c46361ab 100644 --- a/hiro/cocoa/header.hpp +++ b/hiro/cocoa/header.hpp @@ -1,22 +1,6 @@ #define decimal decimal_cocoa -#define int8 int8_cocoa -#define int16 int16_cocoa -#define int32 int32_cocoa -#define int64 int64_cocoa -#define uint8 uint8_cocoa -#define uint16 uint16_cocoa -#define uint32 uint32_cocoa -#define uint64 uint64_cocoa #import #import #undef decimal -#undef int8 -#undef int16 -#undef int32 -#undef int64 -#undef uint8 -#undef uint16 -#undef uint32 -#undef uint64 #include diff --git a/hiro/cocoa/widget/canvas.cpp b/hiro/cocoa/widget/canvas.cpp index 14cd1e15..20947be8 100644 --- a/hiro/cocoa/widget/canvas.cpp +++ b/hiro/cocoa/widget/canvas.cpp @@ -185,7 +185,7 @@ auto pCanvas::_rasterize() -> void { [cocoaView setImage:surface]; } - auto target = (uint32*)[bitmap bitmapData]; + auto target = (uint32_t*)[bitmap bitmapData]; if(auto icon = state().icon) { icon.transform(); @@ -197,7 +197,7 @@ auto pCanvas::_rasterize() -> void { fill.gradient(colors[0].value(), colors[1].value(), colors[2].value(), colors[3].value()); memory::copy(target, fill.data(), fill.size()); } else { - uint32 color = state().color.value(); + uint32_t color = state().color.value(); for(auto n : range(width * height)) target[n] = color; } } diff --git a/icarus/GNUmakefile b/icarus/GNUmakefile index 4cf51b68..d6e84b5a 100644 --- a/icarus/GNUmakefile +++ b/icarus/GNUmakefile @@ -14,7 +14,7 @@ objects += obj/icarus.o objects += $(if $(call streq,$(platform),windows),obj/resource.o) all: $(objects) - $(call unique,$(compiler) -o out/$(name) $(objects) $(link) $(hirolink)) + $(strip $(compiler) -o out/$(name) $(objects) $(link) $(hirolink)) ifeq ($(platform),macosx) @if [ -d out/$(name).app ]; then rm -r out/$(name).app; fi mkdir -p out/$(name).app/Contents/MacOS/ diff --git a/libco/libco.h b/libco/libco.h index 792df0bd..0ea47789 100644 --- a/libco/libco.h +++ b/libco/libco.h @@ -1,5 +1,5 @@ /* - libco v18 (2016-09-14) + libco v18.01 (2017-01-22) author: byuu license: public domain */ diff --git a/libco/settings.h b/libco/settings.h index b419683a..d8037bc4 100644 --- a/libco/settings.h +++ b/libco/settings.h @@ -1,4 +1,4 @@ -#ifdef LIBCO_C +#if defined(LIBCO_C) /*[amd64, arm, ppc, x86]: by default, co_swap_function is marked as a text (code) section @@ -10,8 +10,8 @@ do not use this unless you are certain your application won't use SSE */ /* #define LIBCO_NO_SSE */ -#ifdef LIBCO_C - #ifdef LIBCO_MP +#if defined(LIBCO_C) + #if defined(LIBCO_MP) #define thread_local __thread #else #define thread_local @@ -19,18 +19,20 @@ #endif #if __STDC_VERSION__ >= 201112L - #ifndef _MSC_VER + #if !defined(_MSC_VER) #include #endif #else #define alignas(bytes) #endif -#ifndef _MSC_VER - #define section(name) __attribute__((section("." #name "#"))) -#else +#if defined(_MSC_VER) #define section(name) __declspec(allocate("." #name)) +#elif defined(__APPLE__) + #define section(name) __attribute__((section("__TEXT,__" #name))) +#else + #define section(name) __attribute__((section("." #name "#"))) #endif -/* ifdef LIBCO_C */ +/* if defined(LIBCO_C) */ #endif