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.
This commit is contained in:
Tim Allen 2017-01-23 08:04:26 +11:00
parent c40e9754bc
commit bdc100e123
147 changed files with 855 additions and 894 deletions

View File

@ -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;
}
}

View File

@ -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/";

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -69,9 +69,6 @@ auto APU::DMC::clock() -> uint8 {
}
auto APU::DMC::power() -> void {
}
auto APU::DMC::reset() -> void {
lengthCounter = 0;
irqPending = 0;

View File

@ -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;

View File

@ -26,9 +26,6 @@ auto APU::Noise::clock() -> uint8 {
}
auto APU::Noise::power() -> void {
}
auto APU::Noise::reset() -> void {
lengthCounter = 0;
envelope.speed = 0;

View File

@ -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;

View File

@ -38,6 +38,3 @@ auto APU::Sweep::power() -> void {
reload = 0;
pulsePeriod = 0;
}
auto APU::Sweep::reset() -> void {
}

View File

@ -28,10 +28,6 @@ auto APU::Triangle::clock() -> uint8 {
}
auto APU::Triangle::power() -> void {
reset();
}
auto APU::Triangle::reset() -> void {
lengthCounter = 0;
linearLength = 0;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -34,7 +34,6 @@ struct KonamiVRC6 : Board {
auto main() -> void { vrc6.main(); }
auto power() -> void { vrc6.power(); }
auto reset() -> void { vrc6.reset(); }
VRC6 vrc6;
};

View File

@ -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);

View File

@ -30,9 +30,6 @@ struct NES_AxROM : Board {
}
auto power() -> void {
}
auto reset() -> void {
prgBank = 0x0f;
mirrorSelect = 0;
}

View File

@ -31,9 +31,6 @@ struct NES_BNROM : Board {
}
auto power() -> void {
}
auto reset() -> void {
prgBank = 0;
}

View File

@ -33,9 +33,6 @@ struct NES_CNROM : Board {
}
auto power() -> void {
}
auto reset() -> void {
chrBank = 0;
}

View File

@ -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);

View File

@ -52,9 +52,6 @@ struct NES_FxROM : Board {
}
auto power() -> void {
}
auto reset() -> void {
prgBank = 0;
chrBank[0][0] = 0;
chrBank[0][1] = 0;

View File

@ -37,9 +37,6 @@ struct NES_GxROM : Board {
}
auto power() -> void {
}
auto reset() -> void {
prgBank = 0;
chrBank = 0;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -58,9 +58,6 @@ struct NES_PxROM : Board {
}
auto power() -> void {
}
auto reset() -> void {
prgBank = 0;
chrBank[0][0] = 0;
chrBank[0][1] = 0;

View File

@ -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);

View File

@ -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);

View File

@ -33,9 +33,6 @@ struct NES_UxROM : Board {
}
auto power() -> void {
}
auto reset() -> void {
prgBank = 0;
}

View File

@ -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 {

View File

@ -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 {

View File

@ -15,7 +15,6 @@ struct Cartridge : Thread {
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
auto serialize(serializer&) -> void;

View File

@ -74,9 +74,6 @@ struct MMC1 : Chip {
}
auto power() -> void {
}
auto reset() -> void {
writedelay = 0;
shiftaddr = 0;
shiftdata = 0;

View File

@ -119,9 +119,6 @@ struct MMC3 : Chip {
}
auto power() -> void {
}
auto reset() -> void {
chrMode = 0;
prgMode = 0;
bankSelect = 0;

View File

@ -335,9 +335,6 @@ struct MMC5 : Chip {
}
auto power() -> void {
}
auto reset() -> void {
for(auto& n : exram) n = 0xff;
prgMode = 3;

View File

@ -133,9 +133,6 @@ struct MMC6 : Chip {
}
auto power() -> void {
}
auto reset() -> void {
chrMode = 0;
prgMode = 0;
ramEnable = 0;

View File

@ -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;

View File

@ -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;

View File

@ -55,9 +55,6 @@ struct VRC3 : Chip {
}
auto power() -> void {
}
auto reset() -> void {
prgBank = 0;
irqMode = 0;
irqEnable = 0;

View File

@ -126,9 +126,6 @@ struct VRC4 : Chip {
}
auto power() -> void {
}
auto reset() -> void {
prgMode = 0;
for(auto& n : prgBank) n = 0;
mirror = 0;

View File

@ -227,9 +227,6 @@ struct VRC6 : Chip {
}
auto power() -> void {
}
auto reset() -> void {
prgBank[0] = 0;
prgBank[1] = 0;
chrBank[0] = 0;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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));

View File

@ -8,7 +8,6 @@ struct PPU : Thread {
auto refresh() -> void;
auto power() -> void;
auto reset() -> void;
//memory.cpp
auto readCIRAM(uint11 addr) -> uint8;

View File

@ -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();
}

View File

@ -9,7 +9,6 @@ struct System {
auto save() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
auto init() -> void;
auto term() -> void;

View File

@ -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<bool>()) {
settings.blurEmulation = value.get<bool>();
system.configureVideoEffects();
return true;
}
if(name == "Color Emulation" && value.is<bool>()) {
settings.colorEmulation = value.get<bool>();
system.configureVideoPalette();
return true;
}
return false;
}

View File

@ -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<bool>()) {
settings.blurEmulation = value.get<bool>();
system.configureVideoEffects();
return true;
}
if(name == "Color Emulation" && value.is<bool>()) {
settings.colorEmulation = value.get<bool>();
system.configureVideoPalette();
return true;
}
return false;
}

View File

@ -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<bool>()) {
settings.blurEmulation = value.get<bool>();
system.configureVideoEffects();
return true;
}
if(name == "Color Emulation" && value.is<bool>()) {
settings.colorEmulation = value.get<bool>();
system.configureVideoPalette();
return true;
}
return false;
}
#include "game-boy.cpp"
#include "game-boy-color.cpp"
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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));

View File

@ -18,7 +18,6 @@ struct CPU : Processor::M68K, Thread {
auto lower(Interrupt) -> void;
auto power() -> void;
auto reset() -> void;
vector<Thread*> peripherals;

View File

@ -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();
}

View File

@ -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;

View File

@ -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);
}

View File

@ -8,7 +8,6 @@ struct PSG : Thread {
auto step(uint clocks) -> void;
auto power() -> void;
auto reset() -> void;
};
extern PSG psg;

View File

@ -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();

View File

@ -8,7 +8,6 @@ struct System {
auto save() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
private:
Emulator::Interface* interface = nullptr;

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -6,7 +6,6 @@ struct YM2612 : Thread {
auto step(uint clocks) -> void;
auto power() -> void;
auto reset() -> void;
};
extern YM2612 ym2612;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -25,7 +25,6 @@ struct GSU {
//gsu.cpp
auto power() -> void;
auto reset() -> void;
//instructions.cpp
auto op_add_adc(uint n);

View File

@ -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]();
}

View File

@ -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;

View File

@ -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<void ()> instructionTable[65536];
Bus* bus = nullptr;

View File

@ -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 {

View File

@ -15,7 +15,6 @@ struct R6502 {
auto mdr() const -> uint8;
auto power() -> void;
auto reset() -> void;
auto interrupt() -> void;
auto instruction() -> void;

View File

@ -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();

View File

@ -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<uint8>;
auto serialize(serializer&) -> void;

View File

@ -78,9 +78,6 @@ auto EpsonRTC::unload() -> void {
}
auto EpsonRTC::power() -> void {
}
auto EpsonRTC::reset() -> void {
create(EpsonRTC::Enter, 32'768 * 64);
clocks = 0;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

Some files were not shown because too many files have changed in this diff Show More