Update to v105r1 release.

byuu says:

Changelog:

  - higan: readded support for soft-reset to Famicom, Super Famicom,
    Mega Drive cores (work in progress)
      - handhelds lack soft reset obviously
      - the PC Engine also lacks a physical reset button
      - the Master System's reset button acts like a gamepad button, so
        can't show up in the menu
  - Mega Drive: power cycle wasn't initializing CPU (M68K) or APU (Z80)
    RAM
  - Super Famicom: fix SPC700 opcode 0x3b regression; fixes Majuu Ou
    [Jonas Quinn]
  - Super Famicom: fix SharpRTC save regression; fixes Dai Kaijuu
    Monogatari II's real-time clock [Talarubi]
  - Super Famicom: fix EpsonRTC save regression; fixes Tengai Makyou
    Zero's real-time clock [Talarubi]
  - Super Famicom: removed `*::init()` functions, as they were never used
  - Super Famicom: removed all but two `*::load()` functions, as they
    were not used
  - higan: added option to auto-save backup RAM every five seconds
    (enabled by default)
      - this is in case the emulator crashes, or there's a power outage;
        turn it off under advanced settings if you want
  - libco: updated license from public domain to ISC, for consistency
    with nall, ruby, hiro
  - nall: Linux compiler defaults to g++; override with g++-version if
    g++ is <= 4.8
      - FreeBSD compiler default is going to remain g++49 until my dev
        box OS ships with g++ >= 4.9

Errata: I have weird RAM initialization constants, thanks to hex_usr
and onethirdxcubed for both finding this:
http://wiki.nesdev.com/w/index.php?title=CPU_power_up_state&diff=11711&oldid=11184

I'll remove this in the next WIP.
This commit is contained in:
Tim Allen 2017-11-07 09:05:54 +11:00
parent 6d487925d0
commit e9d2d56df9
89 changed files with 166 additions and 314 deletions

View File

@ -12,7 +12,7 @@ using namespace nall;
namespace Emulator { namespace Emulator {
static const string Name = "higan"; static const string Name = "higan";
static const string Version = "105 (tr1)"; static const string Version = "105.01";
static const string Author = "byuu"; static const string Author = "byuu";
static const string License = "GPLv3"; static const string License = "GPLv3";
static const string Website = "https://byuu.org/"; static const string Website = "https://byuu.org/";

View File

@ -6,7 +6,8 @@ struct Interface {
struct Information { struct Information {
string manufacturer; string manufacturer;
string name; string name;
bool overscan; bool overscan = false;
bool resettable = false;
} information; } information;
struct Medium { struct Medium {
@ -59,6 +60,7 @@ struct Interface {
//system interface //system interface
virtual auto connect(uint port, uint device) -> void {} virtual auto connect(uint port, uint device) -> void {}
virtual auto power() -> void {} virtual auto power() -> void {}
virtual auto reset() -> void {}
virtual auto run() -> void {} virtual auto run() -> void {}
//time functions //time functions

View File

@ -71,7 +71,7 @@ auto APU::setSample(int16 sample) -> void {
cartridgeSample = sample; cartridgeSample = sample;
} }
auto APU::power() -> void { auto APU::power(bool reset) -> void {
create(APU::Enter, system.frequency()); create(APU::Enter, system.frequency());
stream = Emulator::audio.createStream(1, frequency() / rate()); stream = Emulator::audio.createStream(1, frequency() / rate());
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 90.0); stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 90.0);

View File

@ -12,7 +12,7 @@ struct APU : Thread {
auto setIRQ() -> void; auto setIRQ() -> void;
auto setSample(int16 sample) -> void; auto setSample(int16 sample) -> void;
auto power() -> void; auto power(bool reset) -> void;
auto readIO(uint16 addr) -> uint8; auto readIO(uint16 addr) -> uint8;
auto writeIO(uint16 addr, uint8 data) -> void; auto writeIO(uint16 addr, uint8 data) -> void;

View File

@ -24,16 +24,16 @@ auto CPU::step(uint clocks) -> void {
for(auto peripheral : peripherals) synchronize(*peripheral); for(auto peripheral : peripherals) synchronize(*peripheral);
} }
auto CPU::power() -> void { auto CPU::power(bool reset) -> void {
MOS6502::BCD = 0; MOS6502::BCD = 0;
MOS6502::power(); MOS6502::power();
create(CPU::Enter, system.frequency()); create(CPU::Enter, system.frequency());
for(auto addr : range(0x0800)) ram[addr] = 0xff; if(!reset) for(auto& data : ram) data = 0xff;
ram[0x0008] = 0xf7; ram[0x008] = 0xf7; //todo: what is this about?
ram[0x0009] = 0xef; ram[0x009] = 0xef;
ram[0x000a] = 0xdf; ram[0x00a] = 0xdf;
ram[0x000f] = 0xbf; ram[0x00f] = 0xbf;
r.pc.byte(0) = bus.read(0xfffc); r.pc.byte(0) = bus.read(0xfffc);
r.pc.byte(1) = bus.read(0xfffd); r.pc.byte(1) = bus.read(0xfffd);

View File

@ -6,7 +6,7 @@ struct CPU : Processor::MOS6502, Thread {
auto main() -> void; auto main() -> void;
auto step(uint clocks) -> void; auto step(uint clocks) -> void;
auto power() -> void; auto power(bool reset) -> void;
//memory.cpp //memory.cpp
auto readRAM(uint11 addr) -> uint8; auto readRAM(uint11 addr) -> uint8;
@ -37,7 +37,7 @@ struct CPU : Processor::MOS6502, Thread {
//protected: //protected:
vector<Thread*> peripherals; vector<Thread*> peripherals;
uint8 ram[0x0800]; uint8 ram[0x800];
struct IO { struct IO {
bool interruptPending; bool interruptPending;

View File

@ -8,6 +8,7 @@ Interface::Interface() {
information.manufacturer = "Nintendo"; information.manufacturer = "Nintendo";
information.name = "Famicom"; information.name = "Famicom";
information.overscan = true; information.overscan = true;
information.resettable = true;
media.append({ID::Famicom, "Famicom", "fc"}); media.append({ID::Famicom, "Famicom", "fc"});
@ -137,7 +138,11 @@ auto Interface::connect(uint port, uint device) -> void {
} }
auto Interface::power() -> void { auto Interface::power() -> void {
system.power(); system.power(/* reset = */ false);
}
auto Interface::reset() -> void {
system.power(/* reset = */ true);
} }
auto Interface::run() -> void { auto Interface::run() -> void {

View File

@ -38,6 +38,7 @@ struct Interface : Emulator::Interface {
auto connect(uint port, uint device) -> void override; auto connect(uint port, uint device) -> void override;
auto power() -> void override; auto power() -> void override;
auto reset() -> void override;
auto run() -> void override; auto run() -> void override;
auto serialize() -> serializer override; auto serialize() -> serializer override;

View File

@ -54,18 +54,20 @@ auto PPU::refresh() -> void {
Emulator::video.refresh(buffer, 256 * sizeof(uint32), 256, 240); Emulator::video.refresh(buffer, 256 * sizeof(uint32), 256, 240);
} }
auto PPU::power() -> void { auto PPU::power(bool reset) -> void {
create(PPU::Enter, system.frequency()); create(PPU::Enter, system.frequency());
memory::fill(&io, sizeof(IO)); memory::fill(&io, sizeof(IO));
memory::fill(&latch, sizeof(Latches)); memory::fill(&latch, sizeof(Latches));
io.vramIncrement = 1; io.vramIncrement = 1;
for(auto& n : ciram ) n = 0; if(!reset) {
for(auto& n : cgram ) n = 0; for(auto& data : ciram ) data = 0;
for(auto& n : oam ) n = 0; for(auto& data : cgram ) data = 0;
for(auto& data : oam ) data = 0;
}
for(auto& n : buffer) n = 0; for(auto& data : buffer) data = 0;
} }
} }

View File

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

View File

@ -31,7 +31,7 @@ auto System::unserialize(serializer& s) -> bool {
if(signature != 0x31545342) return false; if(signature != 0x31545342) return false;
if(string{version} != Emulator::SerializerVersion) return false; if(string{version} != Emulator::SerializerVersion) return false;
power(); power(/* reset = */ false);
serializeAll(s); serializeAll(s);
return true; return true;
} }

View File

@ -62,7 +62,7 @@ auto System::unload() -> void {
information.loaded = false; information.loaded = false;
} }
auto System::power() -> void { auto System::power(bool reset) -> void {
Emulator::video.reset(); Emulator::video.reset();
Emulator::video.setInterface(interface); Emulator::video.setInterface(interface);
configureVideoPalette(); configureVideoPalette();
@ -73,9 +73,9 @@ auto System::power() -> void {
scheduler.reset(); scheduler.reset();
cartridge.power(); cartridge.power();
cpu.power(); cpu.power(reset);
apu.power(); apu.power(reset);
ppu.power(); ppu.power(reset);
scheduler.primary(cpu); scheduler.primary(cpu);
controllerPort1.power(ID::Port::Controller1); controllerPort1.power(ID::Port::Controller1);

View File

@ -11,7 +11,7 @@ struct System {
auto load(Emulator::Interface*) -> bool; auto load(Emulator::Interface*) -> bool;
auto save() -> void; auto save() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power(bool reset) -> void;
auto init() -> void; auto init() -> void;
auto term() -> void; auto term() -> void;

View File

@ -52,11 +52,13 @@ auto APU::enable(bool value) -> void {
state.enabled = value; state.enabled = value;
} }
auto APU::power() -> void { auto APU::power(bool reset) -> void {
Z80::bus = this; Z80::bus = this;
Z80::power(); Z80::power();
bus->grant(false); bus->grant(false);
create(APU::Enter, system.frequency() / 15.0); create(APU::Enter, system.frequency() / 15.0);
if(!reset) memory::fill(ram, sizeof ram);
state = {}; state = {};
} }

View File

@ -8,7 +8,7 @@ struct APU : Processor::Z80, Processor::Z80::Bus, Thread {
auto synchronizing() const -> bool override; auto synchronizing() const -> bool override;
auto enable(bool) -> void; auto enable(bool) -> void;
auto power() -> void; auto power(bool reset) -> void;
auto reset() -> void; auto reset() -> void;
auto setNMI(bool value) -> void; auto setNMI(bool value) -> void;

View File

@ -80,11 +80,13 @@ auto CPU::load(Markup::Node node) -> bool {
return true; return true;
} }
auto CPU::power() -> void { auto CPU::power(bool reset) -> void {
M68K::bus = this; M68K::bus = this;
M68K::power(); M68K::power();
create(CPU::Enter, system.frequency() / 7.0); create(CPU::Enter, system.frequency() / 7.0);
if(!reset) memory::fill(ram, sizeof ram);
io = {}; io = {};
io.version = tmssEnable; io.version = tmssEnable;
io.romEnable = !tmssEnable; io.romEnable = !tmssEnable;

View File

@ -19,7 +19,7 @@ struct CPU : Processor::M68K, Processor::M68K::Bus, Thread {
auto lower(Interrupt) -> void; auto lower(Interrupt) -> void;
auto load(Markup::Node) -> bool; auto load(Markup::Node) -> bool;
auto power() -> void; auto power(bool reset) -> void;
//bus.cpp //bus.cpp
auto readByte(uint24 address) -> uint16 override; auto readByte(uint24 address) -> uint16 override;

View File

@ -8,6 +8,7 @@ Interface::Interface() {
information.manufacturer = "Sega"; information.manufacturer = "Sega";
information.name = "Mega Drive"; information.name = "Mega Drive";
information.overscan = true; information.overscan = true;
information.resettable = true;
media.append({ID::MegaDrive, "Mega Drive", "md"}); media.append({ID::MegaDrive, "Mega Drive", "md"});
@ -122,7 +123,11 @@ auto Interface::connect(uint port, uint device) -> void {
} }
auto Interface::power() -> void { auto Interface::power() -> void {
system.power(); system.power(/* reset = */ false);
}
auto Interface::reset() -> void {
system.power(/* reset = */ true);
} }
auto Interface::run() -> void { auto Interface::run() -> void {

View File

@ -38,6 +38,7 @@ struct Interface : Emulator::Interface {
auto connect(uint port, uint device) -> void override; auto connect(uint port, uint device) -> void override;
auto power() -> void override; auto power() -> void override;
auto reset() -> void override;
auto run() -> void override; auto run() -> void override;
auto serialize() -> serializer override; auto serialize() -> serializer override;

View File

@ -34,7 +34,7 @@ auto PSG::step(uint clocks) -> void {
synchronize(apu); synchronize(apu);
} }
auto PSG::power() -> void { auto PSG::power(bool reset) -> void {
create(PSG::Enter, system.frequency() / 15.0); create(PSG::Enter, system.frequency() / 15.0);
stream = Emulator::audio.createStream(1, frequency() / 16.0); stream = Emulator::audio.createStream(1, frequency() / 16.0);
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0); stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0);

View File

@ -7,7 +7,7 @@ struct PSG : Thread {
auto main() -> void; auto main() -> void;
auto step(uint clocks) -> void; auto step(uint clocks) -> void;
auto power() -> void; auto power(bool reset) -> void;
//io.cpp //io.cpp
auto write(uint8 data) -> void; auto write(uint8 data) -> void;

View File

@ -48,7 +48,7 @@ auto System::unserialize(serializer& s) -> bool {
if(signature != 0x31545342) return false; if(signature != 0x31545342) return false;
if(string{version} != Emulator::SerializerVersion) return false; if(string{version} != Emulator::SerializerVersion) return false;
power(); power(/* reset = */ false);
serializeAll(s); serializeAll(s);
return true; return true;
} }

View File

@ -61,7 +61,7 @@ auto System::unload() -> void {
cartridge.unload(); cartridge.unload();
} }
auto System::power() -> void { auto System::power(bool reset) -> void {
Emulator::video.reset(); Emulator::video.reset();
Emulator::video.setInterface(interface); Emulator::video.setInterface(interface);
Emulator::video.setPalette(); Emulator::video.setPalette();
@ -71,11 +71,11 @@ auto System::power() -> void {
scheduler.reset(); scheduler.reset();
cartridge.power(); cartridge.power();
cpu.power(); cpu.power(reset);
apu.power(); apu.power(reset);
vdp.power(); vdp.power(reset);
psg.power(); psg.power(reset);
ym2612.power(); ym2612.power(reset);
scheduler.primary(cpu); scheduler.primary(cpu);
controllerPort1.power(ID::Port::Controller1); controllerPort1.power(ID::Port::Controller1);

View File

@ -15,7 +15,7 @@ struct System {
auto load(Emulator::Interface*, maybe<Region> = nothing) -> bool; auto load(Emulator::Interface*, maybe<Region> = nothing) -> bool;
auto save() -> void; auto save() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power(bool reset) -> void;
//serialization.cpp //serialization.cpp
auto serializeInit() -> void; auto serializeInit() -> void;

View File

@ -81,11 +81,17 @@ auto VDP::refresh() -> void {
Emulator::video.refresh(data, 1280 * sizeof(uint32), 1280, 480); Emulator::video.refresh(data, 1280 * sizeof(uint32), 1280, 480);
} }
auto VDP::power() -> void { auto VDP::power(bool reset) -> void {
create(VDP::Enter, system.frequency() / 2.0); create(VDP::Enter, system.frequency() / 2.0);
output = buffer + 16 * 1280; //overscan offset output = buffer + 16 * 1280; //overscan offset
if(!reset) {
for(auto& data : vram.memory) data = 0;
for(auto& data : vsram.memory) data = 0;
for(auto& data : cram.memory) data = 0;
}
io = {}; io = {};
latch = {}; latch = {};
state = {}; state = {};

View File

@ -6,7 +6,7 @@ struct VDP : Thread {
auto step(uint clocks) -> void; auto step(uint clocks) -> void;
auto refresh() -> void; auto refresh() -> void;
auto power() -> void; auto power(bool reset) -> void;
//io.cpp //io.cpp
auto read(uint24 addr) -> uint16; auto read(uint24 addr) -> uint16;
@ -166,7 +166,6 @@ private:
//serialization.cpp //serialization.cpp
auto serialize(serializer&) -> void; auto serialize(serializer&) -> void;
private:
uint16 memory[32768]; uint16 memory[32768];
} vram; } vram;
@ -179,7 +178,6 @@ private:
//serialization.cpp //serialization.cpp
auto serialize(serializer&) -> void; auto serialize(serializer&) -> void;
private:
uint10 memory[40]; uint10 memory[40];
} vsram; } vsram;
@ -192,7 +190,6 @@ private:
//serialization.cpp //serialization.cpp
auto serialize(serializer&) -> void; auto serialize(serializer&) -> void;
private:
uint9 memory[64]; uint9 memory[64];
} cram; } cram;

View File

@ -154,7 +154,7 @@ auto YM2612::step(uint clocks) -> void {
synchronize(apu); synchronize(apu);
} }
auto YM2612::power() -> void { auto YM2612::power(bool reset) -> void {
create(YM2612::Enter, system.frequency() / 7.0); create(YM2612::Enter, system.frequency() / 7.0);
stream = Emulator::audio.createStream(2, frequency() / 144.0); stream = Emulator::audio.createStream(2, frequency() / 144.0);
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0); stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0);

View File

@ -8,7 +8,7 @@ struct YM2612 : Thread {
auto sample() -> void; auto sample() -> void;
auto step(uint clocks) -> void; auto step(uint clocks) -> void;
auto power() -> void; auto power(bool reset) -> void;
//io.cpp //io.cpp
auto readStatus() -> uint8; auto readStatus() -> uint8;

View File

@ -259,14 +259,12 @@ auto Cartridge::loadNECDSP(Markup::Node node) -> void {
auto Cartridge::loadEpsonRTC(Markup::Node node) -> void { auto Cartridge::loadEpsonRTC(Markup::Node node) -> void {
has.EpsonRTC = true; has.EpsonRTC = true;
epsonrtc.initialize();
if(auto fp = platform->open(ID::SuperFamicom, node["ram"]["name"].text(), File::Read)) { if(auto fp = platform->open(ID::SuperFamicom, node["ram"]["name"].text(), File::Read)) {
uint8 data[16] = {0}; uint8 data[16] = {0};
for(auto& byte : data) byte = fp->read(); for(auto& byte : data) byte = fp->read();
epsonrtc.load(data); epsonrtc.load(data);
} }
else {
epsonrtc.load();
}
for(auto leaf : node.find("map")) loadMap(leaf, {&EpsonRTC::read, &epsonrtc}, {&EpsonRTC::write, &epsonrtc}); for(auto leaf : node.find("map")) loadMap(leaf, {&EpsonRTC::read, &epsonrtc}, {&EpsonRTC::write, &epsonrtc});
} }
@ -274,14 +272,12 @@ auto Cartridge::loadEpsonRTC(Markup::Node node) -> void {
auto Cartridge::loadSharpRTC(Markup::Node node) -> void { auto Cartridge::loadSharpRTC(Markup::Node node) -> void {
has.SharpRTC = true; has.SharpRTC = true;
sharprtc.initialize();
if(auto fp = platform->open(ID::SuperFamicom, node["ram"]["name"].text(), File::Read)) { if(auto fp = platform->open(ID::SuperFamicom, node["ram"]["name"].text(), File::Read)) {
uint8 data[16] = {0}; uint8 data[16] = {0};
for(auto& byte : data) byte = fp->read(); for(auto& byte : data) byte = fp->read();
sharprtc.load(data); sharprtc.load(data);
} }
else {
sharprtc.load();
}
for(auto leaf : node.find("map")) loadMap(leaf, {&SharpRTC::read, &sharprtc}, {&SharpRTC::write, &sharprtc}); for(auto leaf : node.find("map")) loadMap(leaf, {&SharpRTC::read, &sharprtc}, {&SharpRTC::write, &sharprtc});
} }

View File

@ -81,15 +81,6 @@ auto ArmDSP::write(uint24 addr, uint8 data) -> void {
} }
} }
auto ArmDSP::init() -> void {
}
auto ArmDSP::load() -> void {
}
auto ArmDSP::unload() -> void {
}
auto ArmDSP::power() -> void { auto ArmDSP::power() -> void {
random.array((uint8*)programRAM, sizeof(programRAM)); random.array((uint8*)programRAM, sizeof(programRAM));
bridge.reset = false; bridge.reset = false;

View File

@ -19,9 +19,6 @@ struct ArmDSP : Processor::ARM7TDMI, Thread {
auto read(uint24 addr, uint8 data) -> uint8; auto read(uint24 addr, uint8 data) -> uint8;
auto write(uint24 addr, uint8 data) -> void; auto write(uint24 addr, uint8 data) -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void; auto power() -> void;
auto reset() -> void; //soft reset auto reset() -> void; //soft reset

View File

@ -30,10 +30,7 @@ auto EpsonRTC::main() -> void {
synchronize(cpu); synchronize(cpu);
} }
auto EpsonRTC::init() -> void { auto EpsonRTC::initialize() -> void {
}
auto EpsonRTC::load() -> void {
secondlo = 0; secondlo = 0;
secondhi = 0; secondhi = 0;
batteryfailure = 1; batteryfailure = 1;
@ -74,9 +71,6 @@ auto EpsonRTC::load() -> void {
test = 0; test = 0;
} }
auto EpsonRTC::unload() -> void {
}
auto EpsonRTC::power() -> void { auto EpsonRTC::power() -> void {
create(EpsonRTC::Enter, 32'768 * 64); create(EpsonRTC::Enter, 32'768 * 64);

View File

@ -4,9 +4,7 @@ struct EpsonRTC : Thread {
static auto Enter() -> void; static auto Enter() -> void;
auto main() -> void; auto main() -> void;
auto init() -> void; auto initialize() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void; auto power() -> void;
auto sync() -> void; auto sync() -> void;

View File

@ -28,12 +28,6 @@ auto Event::main() -> void {
synchronize(cpu); synchronize(cpu);
} }
auto Event::init() -> void {
}
auto Event::load() -> void {
}
auto Event::unload() -> void { auto Event::unload() -> void {
rom[0].reset(); rom[0].reset();
rom[1].reset(); rom[1].reset();

View File

@ -5,8 +5,6 @@
struct Event : Thread { struct Event : Thread {
static auto Enter() -> void; static auto Enter() -> void;
auto main() -> void; auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -25,12 +25,6 @@ auto HitachiDSP::main() -> void {
synchronize(cpu); synchronize(cpu);
} }
auto HitachiDSP::init() -> void {
}
auto HitachiDSP::load() -> void {
}
auto HitachiDSP::unload() -> void { auto HitachiDSP::unload() -> void {
rom.reset(); rom.reset();
ram.reset(); ram.reset();

View File

@ -5,8 +5,6 @@ struct HitachiDSP : Processor::HG51B, Thread {
static auto Enter() -> void; static auto Enter() -> void;
auto main() -> void; auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -31,9 +31,6 @@ auto ICD2::main() -> void {
synchronize(cpu); synchronize(cpu);
} }
auto ICD2::init() -> void {
}
auto ICD2::load() -> bool { auto ICD2::load() -> bool {
GameBoy::superGameBoy = this; GameBoy::superGameBoy = this;
GameBoy::system.load(&gameBoyInterface, GameBoy::System::Model::SuperGameBoy, cartridge.pathID()); GameBoy::system.load(&gameBoyInterface, GameBoy::System::Model::SuperGameBoy, cartridge.pathID());

View File

@ -6,7 +6,6 @@ struct ICD2 : Emulator::Platform, GameBoy::SuperGameBoyInterface, Thread {
static auto Enter() -> void; static auto Enter() -> void;
auto main() -> void; auto main() -> void;
auto init() -> void;
auto load() -> bool; auto load() -> bool;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -5,12 +5,6 @@ namespace SuperFamicom {
#include "serialization.cpp" #include "serialization.cpp"
MCC mcc; MCC mcc;
auto MCC::init() -> void {
}
auto MCC::load() -> void {
}
auto MCC::unload() -> void { auto MCC::unload() -> void {
rom.reset(); rom.reset();
ram.reset(); ram.reset();

View File

@ -4,8 +4,6 @@ struct MCC {
MappedRAM rom; MappedRAM rom;
MappedRAM ram; MappedRAM ram;
auto init() -> void;
auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -39,12 +39,6 @@ auto MSU1::main() -> void {
synchronize(cpu); synchronize(cpu);
} }
auto MSU1::init() -> void {
}
auto MSU1::load() -> void {
}
auto MSU1::unload() -> void { auto MSU1::unload() -> void {
dataFile.reset(); dataFile.reset();
audioFile.reset(); audioFile.reset();

View File

@ -3,8 +3,6 @@ struct MSU1 : Thread {
static auto Enter() -> void; static auto Enter() -> void;
auto main() -> void; auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -43,15 +43,6 @@ auto NECDSP::writeRAM(uint24 addr, uint8 data) -> void {
return uPD96050::writeDP(addr, data); return uPD96050::writeDP(addr, data);
} }
auto NECDSP::init() -> void {
}
auto NECDSP::load() -> void {
}
auto NECDSP::unload() -> void {
}
auto NECDSP::power() -> void { auto NECDSP::power() -> void {
uPD96050::power(); uPD96050::power();
create(NECDSP::Enter, Frequency); create(NECDSP::Enter, Frequency);

View File

@ -8,9 +8,6 @@ struct NECDSP : Processor::uPD96050, Thread {
auto readRAM(uint24 addr, uint8 data) -> uint8; auto readRAM(uint24 addr, uint8 data) -> uint8;
auto writeRAM(uint24 addr, uint8 data) -> void; auto writeRAM(uint24 addr, uint8 data) -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void; auto power() -> void;
auto firmware() const -> vector<uint8>; auto firmware() const -> vector<uint8>;

View File

@ -4,15 +4,6 @@ namespace SuperFamicom {
NSS nss; NSS nss;
auto NSS::init() -> void {
}
auto NSS::load() -> void {
}
auto NSS::unload() -> void {
}
auto NSS::power() -> void { auto NSS::power() -> void {
} }

View File

@ -1,7 +1,4 @@
struct NSS { struct NSS {
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void; auto power() -> void;
auto setDip(uint16 dip) -> void; auto setDip(uint16 dip) -> void;

View File

@ -5,12 +5,6 @@ namespace SuperFamicom {
#include "serialization.cpp" #include "serialization.cpp"
OBC1 obc1; OBC1 obc1;
auto OBC1::init() -> void {
}
auto OBC1::load() -> void {
}
auto OBC1::unload() -> void { auto OBC1::unload() -> void {
ram.reset(); ram.reset();
} }

View File

@ -1,6 +1,4 @@
struct OBC1 { struct OBC1 {
auto init() -> void;
auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -117,12 +117,6 @@ auto SA1::triggerIRQ() -> void {
if(mmio.timer_irqen) mmio.timer_irqcl = 0; if(mmio.timer_irqen) mmio.timer_irqcl = 0;
} }
auto SA1::init() -> void {
}
auto SA1::load() -> void {
}
auto SA1::unload() -> void { auto SA1::unload() -> void {
rom.reset(); rom.reset();
iram.reset(); iram.reset();

View File

@ -10,8 +10,6 @@ struct SA1 : Processor::WDC65816, Thread {
alwaysinline auto interruptPending() const -> bool override; alwaysinline auto interruptPending() const -> bool override;
auto synchronizing() const -> bool override; auto synchronizing() const -> bool override;
auto init() -> void;
auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -7,12 +7,6 @@ SDD1 sdd1;
#include "decompressor.cpp" #include "decompressor.cpp"
#include "serialization.cpp" #include "serialization.cpp"
auto SDD1::init() -> void {
}
void SDD1::load() {
}
auto SDD1::unload() -> void { auto SDD1::unload() -> void {
rom.reset(); rom.reset();
ram.reset(); ram.reset();

View File

@ -1,6 +1,4 @@
struct SDD1 { struct SDD1 {
auto init() -> void;
auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -18,10 +18,7 @@ auto SharpRTC::main() -> void {
synchronize(cpu); synchronize(cpu);
} }
auto SharpRTC::init() -> void { auto SharpRTC::initialize() -> void {
}
auto SharpRTC::load() -> void {
second = 0; second = 0;
minute = 0; minute = 0;
hour = 0; hour = 0;
@ -31,9 +28,6 @@ auto SharpRTC::load() -> void {
weekday = 0; weekday = 0;
} }
auto SharpRTC::unload() -> void {
}
auto SharpRTC::power() -> void { auto SharpRTC::power() -> void {
create(SharpRTC::Enter, 1); create(SharpRTC::Enter, 1);

View File

@ -2,9 +2,7 @@ struct SharpRTC : Thread {
static auto Enter() -> void; static auto Enter() -> void;
auto main() -> void; auto main() -> void;
auto init() -> void; auto initialize() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void; auto power() -> void;
auto sync() -> void; auto sync() -> void;

View File

@ -32,12 +32,6 @@ auto SPC7110::addClocks(uint clocks) -> void {
synchronize(cpu); synchronize(cpu);
} }
auto SPC7110::init() -> void {
}
auto SPC7110::load() -> void {
}
auto SPC7110::unload() -> void { auto SPC7110::unload() -> void {
prom.reset(); prom.reset();
drom.reset(); drom.reset();

View File

@ -6,8 +6,6 @@ struct SPC7110 : Thread {
static auto Enter() -> void; static auto Enter() -> void;
auto main() -> void; auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -31,12 +31,6 @@ auto SuperFX::main() -> void {
} }
} }
auto SuperFX::init() -> void {
}
auto SuperFX::load() -> void {
}
auto SuperFX::unload() -> void { auto SuperFX::unload() -> void {
rom.reset(); rom.reset();
ram.reset(); ram.reset();

View File

@ -5,8 +5,6 @@ struct SuperFX : Processor::GSU, Thread {
//superfx.cpp //superfx.cpp
static auto Enter() -> void; static auto Enter() -> void;
auto main() -> void; auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -60,7 +60,7 @@ auto CPU::load(Markup::Node node) -> bool {
return true; return true;
} }
auto CPU::power() -> void { auto CPU::power(bool reset) -> void {
WDC65816::power(); WDC65816::power();
create(Enter, system.cpuFrequency()); create(Enter, system.cpuFrequency());
coprocessors.reset(); coprocessors.reset();
@ -86,7 +86,7 @@ auto CPU::power() -> void {
bus.map(reader, writer, "00-3f,80-bf:0000-1fff", 0x2000); bus.map(reader, writer, "00-3f,80-bf:0000-1fff", 0x2000);
bus.map(reader, writer, "7e-7f:0000-ffff", 0x20000); bus.map(reader, writer, "7e-7f:0000-ffff", 0x20000);
random.array(wram, sizeof(wram)); if(!reset) random.array(wram, sizeof(wram));
//DMA //DMA
for(auto& channel : this->channel) { for(auto& channel : this->channel) {

View File

@ -10,7 +10,7 @@ struct CPU : Processor::WDC65816, Thread, PPUcounter {
static auto Enter() -> void; static auto Enter() -> void;
auto main() -> void; auto main() -> void;
auto load(Markup::Node) -> bool; auto load(Markup::Node) -> bool;
auto power() -> void; auto power(bool reset) -> void;
//dma.cpp //dma.cpp
auto dmaStep(uint clocks) -> void; auto dmaStep(uint clocks) -> void;

View File

@ -228,11 +228,11 @@ auto DSP::load(Markup::Node node) -> bool {
return true; return true;
} }
auto DSP::power() -> void { auto DSP::power(bool reset) -> void {
create(Enter, system.apuFrequency()); create(Enter, system.apuFrequency());
stream = Emulator::audio.createStream(2, frequency() / 768.0); stream = Emulator::audio.createStream(2, frequency() / 768.0);
random.array(apuram, sizeof(apuram)); if(!reset) random.array(apuram, sizeof(apuram));
memory::fill(&state, sizeof(State)); memory::fill(&state, sizeof(State));
state.noise = 0x4000; state.noise = 0x4000;

View File

@ -14,7 +14,7 @@ struct DSP : Thread {
auto main() -> void; auto main() -> void;
auto load(Markup::Node) -> bool; auto load(Markup::Node) -> bool;
auto power() -> void; auto power(bool reset) -> void;
//serialization.cpp //serialization.cpp
auto serialize(serializer&) -> void; auto serialize(serializer&) -> void;

View File

@ -5,11 +5,10 @@ namespace SuperFamicom {
Settings settings; Settings settings;
Interface::Interface() { Interface::Interface() {
system.init();
information.manufacturer = "Nintendo"; information.manufacturer = "Nintendo";
information.name = "Super Famicom"; information.name = "Super Famicom";
information.overscan = true; information.overscan = true;
information.resettable = true;
media.append({ID::SuperFamicom, "Super Famicom", "sfc"}); media.append({ID::SuperFamicom, "Super Famicom", "sfc"});
@ -194,7 +193,11 @@ auto Interface::connect(uint port, uint device) -> void {
} }
auto Interface::power() -> void { auto Interface::power() -> void {
system.power(); system.power(/* reset = */ false);
}
auto Interface::reset() -> void {
system.power(/* reset = */ true);
} }
auto Interface::run() -> void { auto Interface::run() -> void {

View File

@ -50,6 +50,7 @@ struct Interface : Emulator::Interface {
auto connect(uint port, uint device) -> void override; auto connect(uint port, uint device) -> void override;
auto power() -> void override; auto power() -> void override;
auto reset() -> void override;
auto run() -> void override; auto run() -> void override;
auto rtc() -> bool override; auto rtc() -> bool override;

View File

@ -86,7 +86,7 @@ auto PPU::load(Markup::Node node) -> bool {
return true; return true;
} }
auto PPU::power() -> void { auto PPU::power(bool reset) -> void {
create(Enter, system.cpuFrequency()); create(Enter, system.cpuFrequency());
PPUcounter::reset(); PPUcounter::reset();
memory::fill(output, 512 * 480 * sizeof(uint32)); memory::fill(output, 512 * 480 * sizeof(uint32));
@ -95,7 +95,7 @@ auto PPU::power() -> void {
function<auto (uint24, uint8) -> void> writer{&PPU::writeIO, this}; function<auto (uint24, uint8) -> void> writer{&PPU::writeIO, this};
bus.map(reader, writer, "00-3f,80-bf:2100-213f"); bus.map(reader, writer, "00-3f,80-bf:2100-213f");
random.array((uint8*)vram.data, sizeof(vram.data)); if(!reset) random.array((uint8*)vram.data, sizeof(vram.data));
ppu1.mdr = random.bias(0xff); ppu1.mdr = random.bias(0xff);
ppu2.mdr = random.bias(0xff); ppu2.mdr = random.bias(0xff);

View File

@ -11,7 +11,7 @@ struct PPU : Thread, PPUcounter {
static auto Enter() -> void; static auto Enter() -> void;
auto main() -> void; auto main() -> void;
auto load(Markup::Node) -> bool; auto load(Markup::Node) -> bool;
auto power() -> void; auto power(bool reset) -> void;
auto serialize(serializer&) -> void; auto serialize(serializer&) -> void;

View File

@ -4,13 +4,8 @@ namespace SuperFamicom {
BSMemory bsmemory; BSMemory bsmemory;
auto BSMemory::init() -> void {
}
auto BSMemory::load() -> void { auto BSMemory::load() -> void {
if(memory.size() == 0) { if(!memory.size()) memory.allocate(1024 * 1024);
memory.allocate(1024 * 1024);
}
} }
auto BSMemory::unload() -> void { auto BSMemory::unload() -> void {

View File

@ -1,5 +1,4 @@
struct BSMemory : Memory { struct BSMemory : Memory {
auto init() -> void;
auto load() -> void; auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power() -> void;

View File

@ -6,9 +6,6 @@ namespace SuperFamicom {
SufamiTurboCartridge sufamiturboA; SufamiTurboCartridge sufamiturboA;
SufamiTurboCartridge sufamiturboB; SufamiTurboCartridge sufamiturboB;
auto SufamiTurboCartridge::load() -> void {
}
auto SufamiTurboCartridge::unload() -> void { auto SufamiTurboCartridge::unload() -> void {
rom.reset(); rom.reset();
ram.reset(); ram.reset();

View File

@ -1,5 +1,4 @@
struct SufamiTurboCartridge { struct SufamiTurboCartridge {
auto load() -> void;
auto unload() -> void; auto unload() -> void;
auto serialize(serializer&) -> void; auto serialize(serializer&) -> void;

View File

@ -32,7 +32,7 @@ auto SMP::load(Markup::Node node) -> bool {
return false; return false;
} }
auto SMP::power() -> void { auto SMP::power(bool reset) -> void {
SPC700::power(); SPC700::power();
create(Enter, system.apuFrequency() / 12.0); create(Enter, system.apuFrequency() / 12.0);

View File

@ -11,7 +11,7 @@ struct SMP : Processor::SPC700, Thread {
auto main() -> void; auto main() -> void;
auto load(Markup::Node) -> bool; auto load(Markup::Node) -> bool;
auto power() -> void; auto power(bool reset) -> void;
//serialization.cpp //serialization.cpp
auto serialize(serializer&) -> void; auto serialize(serializer&) -> void;

View File

@ -31,7 +31,7 @@ auto System::unserialize(serializer& s) -> bool {
if(signature != 0x31545342) return false; if(signature != 0x31545342) return false;
if(string{version} != Emulator::SerializerVersion) return false; if(string{version} != Emulator::SerializerVersion) return false;
power(); power(/* reset = */ false);
serializeAll(s); serializeAll(s);
return true; return true;
} }

View File

@ -22,29 +22,6 @@ auto System::runToSave() -> void {
for(auto peripheral : cpu.peripherals) scheduler.synchronize(*peripheral); for(auto peripheral : cpu.peripherals) scheduler.synchronize(*peripheral);
} }
auto System::init() -> void {
icd2.init();
mcc.init();
nss.init();
event.init();
sa1.init();
superfx.init();
armdsp.init();
hitachidsp.init();
necdsp.init();
epsonrtc.init();
sharprtc.init();
spc7110.init();
sdd1.init();
obc1.init();
msu1.init();
bsmemory.init();
}
auto System::term() -> void {
}
auto System::load(Emulator::Interface* interface) -> bool { auto System::load(Emulator::Interface* interface) -> bool {
information = {}; information = {};
@ -72,21 +49,7 @@ auto System::load(Emulator::Interface* interface) -> bool {
} }
if(cartridge.has.ICD2) icd2.load(); if(cartridge.has.ICD2) icd2.load();
if(cartridge.has.MCC) mcc.load();
if(cartridge.has.NSSDIP) nss.load();
if(cartridge.has.Event) event.load();
if(cartridge.has.SA1) sa1.load();
if(cartridge.has.SuperFX) superfx.load();
if(cartridge.has.ARMDSP) armdsp.load();
if(cartridge.has.HitachiDSP) hitachidsp.load();
if(cartridge.has.NECDSP) necdsp.load();
if(cartridge.has.SPC7110) spc7110.load();
if(cartridge.has.SDD1) sdd1.load();
if(cartridge.has.OBC1) obc1.load();
if(cartridge.has.MSU1) msu1.load();
if(cartridge.has.BSMemorySlot) bsmemory.load(); if(cartridge.has.BSMemorySlot) bsmemory.load();
if(cartridge.has.SufamiTurboSlots) sufamiturboA.load(), sufamiturboB.load();
serializeInit(); serializeInit();
this->interface = interface; this->interface = interface;
@ -109,18 +72,14 @@ auto System::unload() -> void {
if(cartridge.has.ICD2) icd2.unload(); if(cartridge.has.ICD2) icd2.unload();
if(cartridge.has.MCC) mcc.unload(); if(cartridge.has.MCC) mcc.unload();
if(cartridge.has.NSSDIP) nss.unload();
if(cartridge.has.Event) event.unload(); if(cartridge.has.Event) event.unload();
if(cartridge.has.SA1) sa1.unload(); if(cartridge.has.SA1) sa1.unload();
if(cartridge.has.SuperFX) superfx.unload(); if(cartridge.has.SuperFX) superfx.unload();
if(cartridge.has.ARMDSP) armdsp.unload();
if(cartridge.has.HitachiDSP) hitachidsp.unload(); if(cartridge.has.HitachiDSP) hitachidsp.unload();
if(cartridge.has.NECDSP) necdsp.unload();
if(cartridge.has.SPC7110) spc7110.unload(); if(cartridge.has.SPC7110) spc7110.unload();
if(cartridge.has.SDD1) sdd1.unload(); if(cartridge.has.SDD1) sdd1.unload();
if(cartridge.has.OBC1) obc1.unload(); if(cartridge.has.OBC1) obc1.unload();
if(cartridge.has.MSU1) msu1.unload(); if(cartridge.has.MSU1) msu1.unload();
if(cartridge.has.BSMemorySlot) bsmemory.unload(); if(cartridge.has.BSMemorySlot) bsmemory.unload();
if(cartridge.has.SufamiTurboSlots) sufamiturboA.unload(), sufamiturboB.unload(); if(cartridge.has.SufamiTurboSlots) sufamiturboA.unload(), sufamiturboB.unload();
@ -128,7 +87,7 @@ auto System::unload() -> void {
information.loaded = false; information.loaded = false;
} }
auto System::power() -> void { auto System::power(bool reset) -> void {
Emulator::video.reset(); Emulator::video.reset();
Emulator::video.setInterface(interface); Emulator::video.setInterface(interface);
configureVideoPalette(); configureVideoPalette();
@ -140,10 +99,10 @@ auto System::power() -> void {
random.entropy(Random::Entropy::Low); random.entropy(Random::Entropy::Low);
scheduler.reset(); scheduler.reset();
cpu.power(); cpu.power(reset);
smp.power(); smp.power(reset);
dsp.power(); dsp.power(reset);
ppu.power(); ppu.power(reset);
if(cartridge.has.ICD2) icd2.power(); if(cartridge.has.ICD2) icd2.power();
if(cartridge.has.MCC) mcc.power(); if(cartridge.has.MCC) mcc.power();
@ -160,7 +119,6 @@ auto System::power() -> void {
if(cartridge.has.SDD1) sdd1.power(); if(cartridge.has.SDD1) sdd1.power();
if(cartridge.has.OBC1) obc1.power(); if(cartridge.has.OBC1) obc1.power();
if(cartridge.has.MSU1) msu1.power(); if(cartridge.has.MSU1) msu1.power();
if(cartridge.has.BSMemorySlot) bsmemory.power(); if(cartridge.has.BSMemorySlot) bsmemory.power();
if(cartridge.has.ICD2) cpu.coprocessors.append(&icd2); if(cartridge.has.ICD2) cpu.coprocessors.append(&icd2);

View File

@ -9,12 +9,10 @@ struct System {
auto run() -> void; auto run() -> void;
auto runToSave() -> void; auto runToSave() -> void;
auto init() -> void;
auto term() -> void;
auto load(Emulator::Interface*) -> bool; auto load(Emulator::Interface*) -> bool;
auto save() -> void; auto save() -> void;
auto unload() -> void; auto unload() -> void;
auto power() -> void; auto power(bool reset) -> void;
//video.cpp //video.cpp
auto configureVideoPalette() -> void; auto configureVideoPalette() -> void;

View File

@ -56,6 +56,8 @@ Settings::Settings() {
set("Input/FocusLoss/Pause", false); set("Input/FocusLoss/Pause", false);
set("Input/FocusLoss/AllowInput", false); set("Input/FocusLoss/AllowInput", false);
set("Emulation/AutoSaveRAM", true);
set("Crashed", false); set("Crashed", false);
} }

View File

@ -72,6 +72,14 @@ auto InputManager::appendHotkeys() -> void {
hotkeys.append(hotkey); hotkeys.append(hotkey);
} }
{ auto hotkey = new InputHotkey;
hotkey->name = "Soft Reset";
hotkey->press = [] {
program->softReset();
};
hotkeys.append(hotkey);
}
{ auto hotkey = new InputHotkey; { auto hotkey = new InputHotkey;
hotkey->name = "Power Cycle"; hotkey->name = "Power Cycle";
hotkey->press = [] { hotkey->press = [] {

View File

@ -42,7 +42,8 @@ Presentation::Presentation() {
} }
systemMenu.setText("System").setVisible(false); systemMenu.setText("System").setVisible(false);
reloadSystem.setText("Power Cycle").onActivate([&] { program->powerCycle(); }); resetSystem.setText("Soft Reset").onActivate([&] { program->softReset(); });
powerSystem.setText("Power Cycle").onActivate([&] { program->powerCycle(); });
unloadSystem.setText("Unload").onActivate([&] { program->unloadMedium(); }); unloadSystem.setText("Unload").onActivate([&] { program->unloadMedium(); });
settingsMenu.setText("Settings"); settingsMenu.setText("Settings");
@ -213,6 +214,7 @@ auto Presentation::updateEmulator() -> void {
} }
systemMenuSeparatorPorts.setVisible(inputPort1.visible() || inputPort2.visible() || inputPort3.visible()); systemMenuSeparatorPorts.setVisible(inputPort1.visible() || inputPort2.visible() || inputPort3.visible());
resetSystem.setVisible(emulator->information.resettable);
emulator->set("Blur Emulation", blurEmulation.checked()); emulator->set("Blur Emulation", blurEmulation.checked());
emulator->set("Color Emulation", colorEmulation.checked()); emulator->set("Color Emulation", colorEmulation.checked());

View File

@ -23,7 +23,8 @@ struct Presentation : Window {
Menu inputPort2{&systemMenu}; Menu inputPort2{&systemMenu};
Menu inputPort3{&systemMenu}; Menu inputPort3{&systemMenu};
MenuSeparator systemMenuSeparatorPorts{&systemMenu}; MenuSeparator systemMenuSeparatorPorts{&systemMenu};
MenuItem reloadSystem{&systemMenu}; MenuItem resetSystem{&systemMenu};
MenuItem powerSystem{&systemMenu};
MenuItem unloadSystem{&systemMenu}; MenuItem unloadSystem{&systemMenu};
Menu settingsMenu{&menuBar}; Menu settingsMenu{&menuBar};
Menu videoScaleMenu{&settingsMenu}; Menu videoScaleMenu{&settingsMenu};

View File

@ -90,6 +90,13 @@ auto Program::main() -> void {
} }
emulator->run(); emulator->run();
if(settings["Emulation/AutoSaveRAM"].boolean()) {
time_t currentTime = time(nullptr);
if(currentTime - autoSaveTime >= 5) {
autoSaveTime = currentTime;
emulator->save();
}
}
} }
auto Program::quit() -> void { auto Program::quit() -> void {

View File

@ -30,6 +30,7 @@ struct Program : Emulator::Platform {
auto initializeAudioDriver() -> void; auto initializeAudioDriver() -> void;
auto initializeInputDriver() -> void; auto initializeInputDriver() -> void;
auto softReset() -> void;
auto powerCycle() -> void; auto powerCycle() -> void;
auto rotateDisplay() -> void; auto rotateDisplay() -> void;
auto connectDevices() -> void; auto connectDevices() -> void;
@ -49,6 +50,8 @@ struct Program : Emulator::Platform {
vector<string> mediumQueue; //for command-line and drag-and-drop loading vector<string> mediumQueue; //for command-line and drag-and-drop loading
vector<string> mediumPaths; //for keeping track of loaded folder locations vector<string> mediumPaths; //for keeping track of loaded folder locations
time_t autoSaveTime = 0; //for automatically saving RAM periodically
string statusText; string statusText;
string statusMessage; string statusMessage;
time_t statusTime = 0; time_t statusTime = 0;

View File

@ -64,10 +64,17 @@ auto Program::initializeInputDriver() -> void {
} }
} }
auto Program::softReset() -> void {
if(!emulator) return;
if(!emulator->information.resettable) return;
emulator->reset();
showMessage("System has been soft reset");
}
auto Program::powerCycle() -> void { auto Program::powerCycle() -> void {
if(!emulator) return; if(!emulator) return;
emulator->power(); emulator->power();
showMessage("Power cycled"); showMessage("System has been power cycled");
} }
auto Program::rotateDisplay() -> void { auto Program::rotateDisplay() -> void {
@ -94,12 +101,12 @@ auto Program::connectDevices() -> void {
} }
auto Program::showMessage(const string& text) -> void { auto Program::showMessage(const string& text) -> void {
statusTime = time(0); statusTime = time(nullptr);
statusMessage = text; statusMessage = text;
} }
auto Program::updateStatusText() -> void { auto Program::updateStatusText() -> void {
time_t currentTime = time(0); time_t currentTime = time(nullptr);
string text; string text;
if((currentTime - statusTime) <= 2) { if((currentTime - statusTime) <= 2) {

View File

@ -43,4 +43,9 @@ AdvancedSettings::AdvancedSettings(TabFrame* parent) : TabFrameItem(parent) {
ignoreManifests.setText("Ignore Manifests").setChecked(settings["Library/IgnoreManifests"].boolean()).onToggle([&] { ignoreManifests.setText("Ignore Manifests").setChecked(settings["Library/IgnoreManifests"].boolean()).onToggle([&] {
settings["Library/IgnoreManifests"].setValue(ignoreManifests.checked()); settings["Library/IgnoreManifests"].setValue(ignoreManifests.checked());
}); });
otherLabel.setText("Other").setFont(Font().setBold());
autoSaveRAM.setText("Auto-Save RAM Periodically").setChecked(settings["Emulation/AutoSaveRAM"].boolean()).onToggle([&] {
settings["Emulation/AutoSaveRAM"].setValue(autoSaveRAM.checked());
});
} }

View File

@ -141,6 +141,8 @@ struct AdvancedSettings : TabFrameItem {
LineEdit libraryLocation{&libraryLayout, Size{~0, 0}}; LineEdit libraryLocation{&libraryLayout, Size{~0, 0}};
Button libraryChange{&libraryLayout, Size{0, 0}}; Button libraryChange{&libraryLayout, Size{0, 0}};
CheckLabel ignoreManifests{&layout, Size{~0, 0}}; CheckLabel ignoreManifests{&layout, Size{~0, 0}};
Label otherLabel{&layout, Size{~0, 0}, 2};
CheckLabel autoSaveRAM{&layout, Size{~0, 0}};
}; };
struct SettingsManager : Window { struct SettingsManager : Window {

View File

@ -3,14 +3,10 @@ body {
color: #fff; color: #fff;
} }
a {
color: #aaf;
}
a:visited {
color: #faf;
}
code { code {
background: #444; background: #444;
} }
a {
color: #aaf;
}

View File

@ -6,41 +6,19 @@
<body> <body>
<b>License:</b><br/><br/> <b>License:</b><br/><br/>
libco is released under the ISC license.<br/> libco is released under the ISC license.
<br/>
Copyright &copy; 2006-2017 byuu<br/>
<br/>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.<br/>
<br/>
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
<hr/>
<b>Contact:</b><br/><br/>
At present, you may contact me as <b>byuu</b> at
<a href="https://board.byuu.org">https://board.byuu.org</a>.<br/>
I am interested in knowing of any projects that make use of this library,
though this is only a courtesy.
<hr/> <hr/>
<b>Foreword:</b><br/><br/> <b>Foreword:</b><br/><br/>
libco is a cross-platform, permissively licensed implementation of libco is a cross-platform, permissively licensed implementation of
cooperative-multithreading; a feature that is sorely lacking cooperative-multithreading; a feature that is sorely lacking from the ISO C/C++
from the ISO C/C++ standard.<br/> standard.<br/>
The library is designed for maximum speed and portability, and The library is designed for maximum speed and portability, and not for safety or
not for safety or features. If safety or extra functionality is desired, features. If safety or extra functionality is desired, a wrapper API can easily
a wrapper API can easily be written to encapsulate all library functions.<br/> be written to encapsulate all library functions.<br/>
Behavior of executing operations that are listed as not permitted Behavior of executing operations that are listed as not permitted below result
below result in undefined behavior. They may work anyway, they in undefined behavior. They may work anyway, they may cause undesired / unknown
may cause undesired / unknown behavior, or they may crash the behavior, or they may crash the program entirely.<br/>
program entirely.<br/>
The goal of this library was to simplify the base API as much as possible, The goal of this library was to simplify the base API as much as possible,
implementing only that which cannot be implemented using pure C. Additional implementing only that which cannot be implemented using pure C. Additional
functionality after this would only complicate ports of this library to new functionality after this would only complicate ports of this library to new
@ -50,13 +28,12 @@ platforms.
<b>Porting:</b><br/><br/> <b>Porting:</b><br/><br/>
This document is included as a reference for porting libco. Please submit any This document is included as a reference for porting libco. Please submit any
ports you create to me, so that libco can become more useful. Please note that ports you create to me, so that libco can become more useful. Please note that
since libco is ISC, you must submit your code as a work of the public domain, since libco is permissively licensed, you must submit your code as a work of the
or under the same license, in order for it to be included in the official public domain in order for it to be included in the official distribution.
distribution. Full credit will be given in the source code of the official Full credit will be given in the source code of the official release. Please
release. Please do not bother submitting code to me under any other do not bother submitting code to me under any other license -- including GPL,
license&mdash;including GPL, LGPL, BSD or CC&mdash;I am not interested in LGPL, BSD or CC -- I am not interested in creating a library with multiple
creating a library with multiple different licenses depending on which targets different licenses depending on which targets are used.
are used.
<hr/> <hr/>
<b>Synopsis:</b><br/><br/> <b>Synopsis:</b><br/><br/>

View File

@ -1,5 +1,5 @@
/* /*
libco v18.01 (2017-01-22) libco v18.02 (2017-11-06)
author: byuu author: byuu
license: ISC license: ISC
*/ */

View File

@ -51,7 +51,7 @@ ifeq ($(compiler),)
else ifeq ($(platform),macos) else ifeq ($(platform),macos)
compiler := clang++ compiler := clang++
else ifeq ($(platform),linux) else ifeq ($(platform),linux)
compiler := g++-4.9 compiler := g++
else ifeq ($(platform),bsd) else ifeq ($(platform),bsd)
compiler := g++49 compiler := g++49
else else
@ -89,6 +89,7 @@ endif
# windows settings # windows settings
ifeq ($(platform),windows) ifeq ($(platform),windows)
link += -lws2_32 -lole32 link += -lws2_32 -lole32
link += $(if $(findstring $(console),true),-mconsole,-mwindows)
windres := windres windres := windres
endif endif